約 4,620,186 件
https://w.atwiki.jp/oreyome/pages/38.html
kailleraを使ったネット対戦の仕方 Snesでは、Snes9k ver.0.09zでしかカイレラは使えないのでHPへ http //goebish.free.fr/snes9k/ サイト中部にある『version 0.09z』をDL 英語表記なので日本語化をすると見やすくなる http //www.geocities.co.jp/SiliconValley-SanJose/7271/index/hanger/soft.html 『Snes9k Version0.09z 日本語化パッチ』をDL パッチファイルを本体のあるフォルダで展開すれば日本語化完了 初期設定
https://w.atwiki.jp/babylon224/pages/14.html
コントローラー設定 1 Input→InputConfiguration... 注意:赤いカッコは設定しなくてもいい所です。 今のところコントローラーだけの設定でいいはず・・・ ですが3P以上の場合は「5-Player」設定が必要です
https://w.atwiki.jp/oreyome/pages/39.html
kailleraを使ったネット対戦の仕方(Snesで2~5人編) Snesでは、Snes9k ver.0.09zでしかカイレラは使えないのでHPへ http //goebish.free.fr/snes9k/ サイト中部にある『version 0.09z』をDL 英語表記なので日本語化をすると見やすくなる http //www.geocities.co.jp/SiliconValley-SanJose/7271/index/hanger/soft.html 『Snes9k Version0.09z 日本語化パッチ』をDL パッチファイルを本体のあるフォルダで展開すれば日本語化完了 ロム入手方法 吸い出し機を、買うか自作する 基本設定 本体を起動したら、まずはメニューから入力⇒マルチタップを使用するをオンにする (3人以上なら毎回やるようにする) (1)オプション⇒設定 の入力設定 セーブの保存フォルダは本体と同じ場所を指定する(場所が分かればどこでも) S-RAM自動保存→0 最大スキップ数→10 ターボモード→15 一番下にあるターボモードに切り替えはチェックを入れる (2)サウンド⇒設定 の入力設定 サウンドドライバ→Snes9x DirectSound サウンドレート→32kHz ミックス間隔→20ms バッファ長→40ms その他のチェックについては、 左側は 1・2・4番目に、 右側は 1・2・4・7番目にチェックを入れる (3)ファイル⇒kaillera 設定 の入力設定 マルチタップを使用のみチェックを入れる (4)ファイル⇒kaillera開始 の設定 開始すると新たにAnti3D Master v0.9というウィンドウが表示される*1 ユーザー名を設定し、接続形式をExcellentにする サーバーに入ると(Kairellav 0.9 サーバー名)というウィンドウが表示される*2 あとは参加したいゲームに参加してネット対戦開始! *1kailleraウィンドウの説明 All servers:全サーバーが表示される 表示に暫く時間が掛かる Recent:一度入ったサーバーが表示される ここから入れば待たなくてもサーバーに入れる Favorites:現在は使えない Waiting Games:現在待機中のゲームが表示される ゲーム名とその媒体名が載っていて便利 Options:音やメッセージの設定が行える 変更の必要性はないが変更自体はしても問題ない また、Refresh listボタンでサーバー更新、IP入力ボタンでアドレスからサーバーに入れる *2サーバーウィンドウの説明 右上:クライアントの一覧 左上:パーティライン ⇒サーバー内でのクライアントの動き チャットの文章はここに表示される 下半分:カレントゲーム ⇒現在開催されているゲームが表示されている 参加する場合は、参加ボタンを押す 自分が主催する場合は、新規ゲームボタンからゲームを選択する (予め一度読み込む必要がある 圧縮ファイル形式のROMはちゃんと解凍しておくこと) kailleraが成功しない場合に注意する点をいくつかメモ プレイするだけで毎回生成されるセーブファイル(.srm)は、削除する kaillera接続形式を互いにExcellentにすると、片方だけ画面が表示しない現象が解消する ping値の互いに小さな値のサーバーや安定したサーバーを選択するとスムーズに対戦できる 重くなり、同期ずれを起こす原因となるため、SNES以外のプログラムはすべて終了しておく プレイ中にカイレラのチャットをすると同期ずれを起こすことがある 参加自体が出来ない時は、相手とエミュやロムが同じバージョンかどうかの確認をする
https://w.atwiki.jp/snesspec/pages/33.html
オペコード ニーモニック アドレッシングモード バイト サイクル 参照 00 BRK Stack/Interrupt 2** 7 9 01 ORA DP Indexed Indirect,X 2 6 1,2 02 COP Stack/Interrupt 2** 7 9 03 ORA Stack Relative 2 4 1 04 TSB Direct Page 2 5 2,5 05 ORA Direct Page 2 3 1,2 06 ASL Direct Page 2 5 2,5 07 ORA Direct Page Indirect Long 2 6 1,2 08 PHP Stack (Push) 1 3 09 ORA Immediate 2* 2 1 0A ASL Accumulator 1 2 0B PHD Stack (Push) 1 4 0C TSB Absolute 3 6 5 0D ORA Absolute 3 4 1 0E ASL Absolute 3 6 5 0F ORA Absolute Long 4 5 1 10 BPL Program Counter Relative 2 2 7,8 11 ORA DP Indirect Indexed,Y 2 5 1,2,3 12 ORA Direct Page Indirect 2 5 1,2 13 ORA SR Indirect Indexed,Y 2 7 1 14 TRB Direct Page 2 5 2,5 15 ORA Direct Page Indexed,X 2 4 1,2 16 ASL Direct Page Indexed,X 2 6 2,5 17 ORA DP Indirect Long Indexed,Y 2 6 1,2 18 CLC Implied 1 2 19 ORA Absolute Indexed,Y 3 4 1,3 1A INC Accumulator (INA) 1 2 1B TCS Implied 1 2 1C TRB Absolute 3 6 5 1D ORA Absolute Indexed,X 3 4 1,3 1E ASL Absolute Indexed,X 3 7 5,6 1F ORA Absolute Long Indexed,X 4 5 1 20 JSR Absolute 3 6 21 AND DP Indexed Indirect,X 2 6 1,2 22 JSR Absolute Long 4 8 23 AND Stack Relative 2 4 1 24 BIT Direct Page 2 3 1,2 25 AND Direct Page 2 3 1,2 26 ROL Direct Page 2 5 2,5 27 AND Direct Page Indirect Long 2 6 1,2 28 PLP Stack (Pull) 1 4 29 AND Immediate 2* 2 1 2A ROL Accumulator 1 2 2B PLD Stack (Pull) 1 5 2C BIT Absolute 3 4 1 2D AND Absolute 3 4 1 2E ROL Absolute 3 6 5 2F AND Absolute Long 4 5 1 30 BMI Program Counter Relative 2 2 7,8 31 AND DP Indirect Indexed,Y 2 5 1,2,3 32 AND Direct Page Indirect 2 5 1,1 33 AND SR Indirect Indexed,Y 2 7 1 34 BIT Direct Page Indexed,X 2 4 1,2 35 AND Direct Page Indexed,X 2 4 1,2 36 ROL Direct Page Indexed,X 2 6 2,5 37 AND DP Indirect Long Indexed,Y 2 6 1,2 38 SEC Implied 1 2 39 AND Absolute Indexed,Y 3 4 1,3 3A DEC Accumulator 1 2 3B TSC Implied 1 2 3C BIT Absolute Indexed,X 3 4 1,3 3D AND Absolute Indexed,X 3 4 1,3 3E ROL Absolute Indexed,X 3 7 5,6 3F AND Absolute Long Indexed,X 4 5 1 40 RTI Stack/RTI 1 6 9 41 EOR DP Indexed Indirect,X 2 6 1,2 42 WDM 2 16 43 EOR Stack Relative 2 4 1 44 MVP Block Move 3 13 45 EOR Direct Page 2 3 1,2 46 LSR Direct Page 2 5 2,5 47 EOR Direct Page Indirect Long 2 6 1,2 48 PHA Stack (Push) 1 3 1 49 EOR Immediate 2* 2 1 4A LSR Accumulator 1 2 4B PHK Stack (Push) 1 3 4C JMP Absolute 3 3 4D EOR Absolute 3 4 1 4E LSR Absolute 3 6 5 4F EOR Absolute Long 4 5 1 50 BVC Program Counter Relative 2 2 7,8 51 EOR DP Indirect Indexed,Y 2 5 1,2,3 52 EOR Direct Page Indirect 2 5 1,2 53 EOR SR Indirect Indexed,Y 2 7 1 54 MVN Block Move 3 13 55 EOR Direct Page Indexed,X 2 4 1,2 56 LSR Direct Page Indexed,X 2 6 2,5 57 EOR DP Indirect Long Indexed,Y 2 6 1,2 58 CLI Implied 1 2 59 EOR Absolute Indexed,Y 3 4 1,3 5A PHY Stack (Push) 1 3 10 5B TCD Implied 1 2 5C JMP Absolute Long 4 4 5D EOR Absolute Indexed,X 3 4 1,3 5E LSR Absolute Indexed,X 3 7 5,6 5F EOR Absolute Long Indexed,X 4 5 1 60 RTS Stack (RTS) 1 6 61 ADC DP Indexed Indirect,X 2 6 1,2,4 62 PER Stack (PC Relative Long) 3 6 63 ADC Stack Relative 2 4 1,4 64 STZ Direct Page 2 3 1,2 65 ADC Direct Page 2 3 1,2,4 66 ROR Direct Page 2 5 1 67 ADC Direct Page Indirect Long 2 6 1,4 68 PLA Stack (Pull) 1 4 1 69 ADC Immediate 2* 2 1,4 6A ROR Accumulator 1 2 6B RTL Stack (RTL) 1 6 6C JMP Absolute Indirect 3 5 11,12 6D ADC Absolute 3 4 1,4 6E ROR Absolute 3 6 5 6F ADC Absolute Long 4 5 1,4 70 BVS Program Counter Relative 2 2 7,8 71 ADC DP Indirect Indexed,Y 2 5 1,2,3,4 72 ADC Direct Page Indirect 2 5 1,2,4 73 ADC SR Indirect Indexed,Y 2 7 1,4 74 STZ Direct Page Indexed,X 2 4 1,2 75 ADC Direct Page Indexed,X 2 4 1,2,4 76 ROR Direct Page Indexed,X 2 6 2,5 77 ADC DP Indirect Long Indexed,Y 2 6 1,2,4 78 SEI Implied 1 2 79 ADC Absolute Indexed,Y 3 4 1,3,4 7A PLY Stack (Pull) 1 4 10 7B TDC Implied 1 2 7C JMP Absolute Indexed Indirect 3 6 7D ADC Absolute Indexed,X 3 4 1,3,4 7E ROR Absolute Indexed,X 3 7 5,6 7F ADC Absolute Long Indexed,X 4 5 1,4 80 BRA Program Counter Relative 2 3 8 81 STA DP Indexed Indirect,X 2 6 1,2 82 BRL Program Counter Relative Long 3 4 83 STA Stack Relative 2 4 1 84 STY Direct Page 2 3 2,10 85 STA Direct Page 2 3 1,2 86 STX Direct Page 2 3 2,10 87 STA Direct Page Indirect Long 2 6 1,2 88 DEY Implied 1 2 89 BIT Immediate 2* 2 1 8A TXA Implied 1 2 8B PHB Stack (Push) 1 3 8C STY Absolute 3 4 10 8D STA Absolute 3 4 1 8E STX Absolute 3 4 10 8F STA Absolute Long 4 5 1 90 BCC Program Counter Relative 2 2 7,8 91 STA DP Indirect Indexed,Y 2 6 1,2 92 STA Direct Page Indirect 2 5 1,2 93 STA SR Indirect Indexed,Y 2 7 1 94 STY Direct Page Indexed,X 2 4 2,10 95 STA Direct Page Indexed,X 2 4 1,2 96 STX Direct Page Indexed,Y 2 4 2,10 97 STA DP Indirect Long Indexed,Y 2 6 1,2 98 TYA Implied 1 2 99 STA Absolute Indexed,Y 3 5 1 9A TXS Implied 1 2 9B TXY Implied 1 2 9C STZ Absolute 3 4 1 9D STA Absolute Indexed,X 3 5 1 9E STZ Absolute Indexed,X 3 5 1 9F STA Absolute Long Indexed,X 4 5 1 A0 LDY Immediate 2+ 2 10 A1 LDA DP Indexed Indirect,X 2 6 1,2 A2 LDX Immediate 2+ 2 10 A3 LDA Stack Relative 2 4 1 A4 LDY Direct Page 2 3 2,10 A5 LDA Direct Page 2 3 1,2 A6 LDX Direct Page 2 3 2,10 A7 LDA Direct Page Indirect Long 2 6 1,2 A8 TAY Implied 1 2 A9 LDA Immediate 2* 2 1 AA TAX Implied 1 2 AB PLB Stack (Pull) 1 4 AC LDY Absolute 3 4 10 AD LDA Absolute 3 4 1 AE LDX Absolute 3 4 10 AF LDA Absolute Long 4 5 1 B0 BCS Program Counter Relative 2 2 7,8 B1 LDA DP Indirect Indexed,Y 2 5 1,2,3 B2 LDA Direct Page Indirect 2 5 1,2 B3 LDA SR Indirect Indexed,Y 2 7 1 B4 LDY Direct Page Indexed,X 2 4 2,10 B5 LDA Direct Page Indexed,X 2 4 1,2 B6 LDX DP Indexed,Y 2 4 2,10 B7 LDA DP Indirect Long Indexed,Y 2 6 1,2 B8 CLV Implied 1 2 B9 LDA Absolute Indexed,Y 3 4 1,3 BA TSX Implied 1 2 BB TYX Implied 1 2 BC LDY Absolute Indexed,X 3 4 3,10 BD LDA Absolute Indexed,X 3 4 1,3 BE LDX Absolute Indexed,Y 3 4 3,10 BF LDA Absolute Long Indexed,X 4 5 1 C0 CPY Immediate 2+ 2 10 C1 CMP DP Indexed Indirect,X 2 6 1,2 C2 REP Immediate 2 3 C3 CMP Stack Relative 2 4 1 C4 CPY Direct Page 2 3 2,10 C5 CMP Direct Page 2 3 1,2 C6 DEC Direct Page 2 5 2,5 C7 CMP Direct Page Indirect Long 2 6 1,2 C8 INY Implied 1 2 C9 CMP Immediate 2* 2 1 CA DEX Implied 1 2 CB WAI Implied 1 3 15 CC CPY Absolute 3 4 10 CD CMP Absolute 3 4 1 CE DEC Absolute 3 6 5 CF CMP Absolute Long 4 5 1 D0 BNE Program Counter Relative 2 2 7,8 D1 CMP DP Indirect Indexed,Y 2 5 1,2,3 D2 CMP Direct Page Indirect 2 5 1,2 D3 CMP SR Indirect Indexed,Y 2 7 1 D4 PEI Stack (Direct Page Indirect) 2 6 2 D5 CMP Direct Page Indexed,X 2 4 1,2 D6 DEC Direct Page Indexed,X 2 6 2,5 D7 CMP DP Indirect Long Indexed,Y 2 6 1,2 D8 CLD Implied 1 2 D9 CMP Absolute Indexed,Y 3 4 1,3 DA PHX Stack (Push) 1 3 10 DB STP Implied 1 3 14 DC JMP Absolute Indirect Long 3 6 DD CMP Absolute Indexed,X 3 4 1,3 DE DEC Absolute Indexed,X 3 7 5,6 DF CMP Absolute Long Indexed,X 4 5 1 E0 CPX Immediate 2+ 2 10 E1 SBC DP Indexed Indirect,X 2 6 1,2,4 E2 SEP Immediate 2 3 E3 SBC Stack Relative 2 4 1,4 E4 CPX Direct Page 2 3 2,10 E5 SBC Direct Page 2 3 1,2,4 E6 INC Direct Page 2 5 E7 SBC Direct Page Indirect Long 2 6 1,2,4 E8 INX Implied 1 2 E9 SBC Immediate 2* 2 EA NOP Implied 1 2 EB XBA Implied 1 3 EC CPX Absolute 3 4 10 ED SBC Absolute 3 4 1,4 EE INC Absolute 3 6 5 EF SBC Absolute Long 4 5 1,4 F0 BEQ Program Counter Relative 2 2 7,8 F1 SBC DP Indirect Indexed,Y 2 5 1,2,3,4 F2 SBC Direct Page Indirect 2 5 1,2,4 F3 SBC SR Indirect Indexed,Y 2 7 1,4 F4 PEA Stack (Absolute) 3 5 F5 SBC Direct Page Indexed,X 2 4 1,2,4 F6 INC Direct Page Indexed,X 2 6 2,5 F7 SBC DP Indirect Long Indexed,Y 2 6 1,2,4 F8 SED Implied 1 2 F9 SBC Absolute Indexed,Y 3 4 1,3,4 FA PLX Stack (Pull) 1 4 10 FB XCE Implied 1 2 FC JSR Absolute Indexed Indirect 3 8 FD SBC Absolute Indexed,X 3 4 1,3,4 FE INC Absolute Indexed,X 3 7 5,6 FF SBC Absolute Long Indexed,X 4 5 1,4 注 * m=0 (16 bit メモリ/アキュームレータ) の時、1 追加 ** オペコードは 1 バイトだが、プログラムカウンタはスタックに 2 インクリメントして詰まれ、追加のシグネチャバイトが可能 + x=0 (16 bit インデックスレジスタ)の時、1 バイト追加 1 m=0 (16 bit メモリ/アキュームレータ) の時、1 サイクル追加 2 ダイレクトページ (ゼロページ) レジスタの下位バイトが 0 以外の時、1 サイクル追加 3 インデックス加算時にページ境界をまたいだ時、 1 サイクル追加 4 CPU が 65C02 で、d=1 の時、1 サイクル追加 (デシマルモードは 65C02 のみで有効) 5 m=0 (16 bit メモリ/アキュームレータ) の時、 2 サイクル追加 6 CPU が 65C02 で、ページ境界をまたがない時、1 サイクル減少 7 分岐した時、 1 サイクル追加 8 65C02, 65816/65082 のエミュレーションモード (e=1) 時に、 分岐でページ境界をまたいだ時、1 サイクル追加 9 65802/65816 ネイティブモードの時 (e=0)、 1 サイクル追加 10 x=0 (16 bit インデックスレジスタ) の時、1 サイクル追加 11 CPU が 65C02 の時、 1 サイクル追加 12 6502 オペランドの下位バイトが $FF の時 (オペランドが $xxFF) 不正な結果が得られる 13 1 バイト転送ごとに 7 サイクル 14 プロセッサ停止に 3 サイクル使う。リセットされると、CPU がリスタートするために 追加のサイクルが必要になる 15 プロセッサ停止に 3 サイクル使う。 割り込みによりリスタートされる時に、 追加のサイクルが必要になる 16 WDM の 2 バイトの長さの異なるオペコードにより バイト数とサイクル数は将来のプロセッサでは変更されることがある。
https://w.atwiki.jp/snesspec/pages/159.html
ニーモニック コード バイト数 サイクル数 実行内容 フラグ NOP 00 1 2 do nothing ........ TCALL 0 01 1 8 CALL [$FFDE] ........ SET1 d.0 02 2 4 d.0 = 1 ........ BBS d.0, r 03 3 5/7 PC+=r if d.0 == 1 ........ OR A, d 04 2 3 A = A | (d) N.....Z. OR A, !a 05 3 4 A = A | (a) N.....Z. OR A, (X) 06 1 3 A = A | (X) N.....Z. OR A, [d+X] 07 2 6 A = A | ([d+X]) N.....Z. OR A, #i 08 2 2 A = A | i N.....Z. OR dd, ds 09 3 6 (dd) = (dd) | (ds) N.....Z. OR1 C, m.b 0A 3 5 C = C | (m.b) .......C ASL d 0B 2 4 Left shift (d) as above N.....ZC ASL !a 0C 3 5 Left shift (a) as above N.....ZC PUSH PSW 0D 1 4 (SP--) = Flags ........ TSET1 !a 0E 3 6 (a) = (a) | A, ZN as for A-(a) N.....Z. BRK 0F 1 8 PUSH PC AND Flags, PC = [$FFDE] ...1.0.. BPL r 10 2 2/4 PC+=r if N == 0 ........ TCALL 1 11 1 8 CALL [$FFDC] ........ CLR1 d.0 12 2 4 d.0 = 0 ........ BBC d.0, r 13 3 5/7 PC+=r if d.0 == 0 ........ OR A, d+X 14 2 4 A = A | (d+X) N.....Z. OR A, !a+X 15 3 5 A = A | (a+X) N.....Z. OR A, !a+Y 16 3 5 A = A | (a+Y) N.....Z. OR A, [d]+Y 17 2 6 A = A | ([d]+Y) N.....Z. OR d, #i 18 3 5 (d) = (d) | i N.....Z. OR (X), (Y) 19 1 5 (X) = (X) | (Y) N.....Z. DECW d 1A 2 6 Word (d)-- N.....Z. ASL d+X 1B 2 5 Left shift (d+X) as above N.....ZC ASL A 1C 1 2 Left shift A high- C, 0- low N.....ZC DEC X 1D 1 2 X-- N.....Z. CMP X, !a 1E 3 4 X - (a) N.....ZC JMP [!a+X] 1F 3 6 PC = [a+X] ........ CLRP 20 1 2 P = 0 ..0..... TCALL 2 21 1 8 CALL [$FFDA] ........ SET1 d.1 22 2 4 d.1 = 1 ........ BBS d.1, r 23 3 5/7 PC+=r if d.1 == 1 ........ AND A, d 24 2 3 A = A (d) N.....Z. AND A, !a 25 3 4 A = A (a) N.....Z. AND A, (X) 26 1 3 A = A (X) N.....Z. AND A, [d+X] 27 2 6 A = A ([d+X]) N.....Z. AND A, #i 28 2 2 A = A i N.....Z. AND dd, ds 29 3 6 (dd) = (dd) (ds) N.....Z. OR1 C, /m.b 2A 3 5 C = C | ~(m.b) .......C ROL d 2B 2 4 Left shift (d) as above N.....ZC ROL !a 2C 3 5 Left shift (a) as above N.....ZC PUSH A 2D 1 4 (SP--) = A ........ CBNE d, r 2E 3 5/7 CMP A, (d) then BNE ........ BRA r 2F 2 4 PC+=r ........ BMI r 30 2 2/4 PC+=r if N == 1 ........ TCALL 3 31 1 8 CALL [$FFD8] ........ CLR1 d.1 32 2 4 d.1 = 0 ........ BBC d.1, r 33 3 5/7 PC+=r if d.1 == 0 ........ AND A, d+X 34 2 4 A = A (d+X) N.....Z. AND A, !a+X 35 3 5 A = A (a+X) N.....Z. AND A, !a+Y 36 3 5 A = A (a+Y) N.....Z. AND A, [d]+Y 37 2 6 A = A ([d]+Y) N.....Z. AND d, #i 38 3 5 (d) = (d) i N.....Z. AND (X), (Y) 39 1 5 (X) = (X) (Y) N.....Z. INCW d 3A 2 6 Word (d)++ N.....Z. ROL d+X 3B 2 5 Left shift (d+X) as above N.....ZC ROL A 3C 1 2 Left shift A low=C, C=high N.....ZC INC X 3D 1 2 X++ N.....Z. CMP X, d 3E 2 3 X - (d) N.....ZC CALL !a 3F 3 8 (SP--)=PCh, (SP--)=PCl, PC=a ........ SETP 40 1 2 P = 1 ..1..... TCALL 4 41 1 8 CALL [$FFD6] ........ SET1 d.2 42 2 4 d.2 = 1 ........ BBS d.2, r 43 3 5/7 PC+=r if d.2 == 1 ........ EOR A, d 44 2 3 A = A EOR (d) N.....Z. EOR A, !a 45 3 4 A = A EOR (a) N.....Z. EOR A, (X) 46 1 3 A = A EOR (X) N.....Z. EOR A, [d+X] 47 2 6 A = A EOR ([d+X]) N.....Z. EOR A, #i 48 2 2 A = A EOR i N.....Z. EOR dd, ds 49 3 6 (dd) = (dd) EOR (ds) N.....Z. AND1 C, m.b 4A 3 4 C = C (m.b) .......C LSR d 4B 2 4 Right shift (d) as above N.....ZC LSR !a 4C 3 5 Right shift (a) as above N.....ZC PUSH X 4D 1 4 (SP--) = X ........ TCLR1 !a 4E 3 6 (a) = (a) ~A, ZN as for A-(a) N.....Z. PCALL u 4F 2 6 CALL $FF00+u ........ BVC r 50 2 2/4 PC+=r if V == 0 ........ TCALL 5 51 1 8 CALL [$FFD4] ........ CLR1 d.2 52 2 4 d.2 = 0 ........ BBC d.2, r 53 3 5/7 PC+=r if d.2 == 0 ........ EOR A, d+X 54 2 4 A = A EOR (d+X) N.....Z. EOR A, !a+X 55 3 5 A = A EOR (a+X) N.....Z. EOR A, !a+Y 56 3 5 A = A EOR (a+Y) N.....Z. EOR A, [d]+Y 57 2 6 A = A EOR ([d]+Y) N.....Z. EOR d, #i 58 3 5 (d) = (d) EOR i N.....Z. EOR (X), (Y) 59 1 5 (X) = (X) EOR (Y) N.....Z. CMPW YA, d 5A 2 4 YA - (d) N.....ZC LSR d+X 5B 2 5 Right shift (d+X) as above N.....ZC LSR A 5C 1 2 Right shift A 0- high, low- C N.....ZC MOV X, A 5D 1 2 X = A N.....Z. CMP Y, !a 5E 3 4 Y - (a) N.....ZC JMP !a 5F 3 3 PC = a ........ CLRC 60 1 2 C = 0 .......0 TCALL 6 61 1 8 CALL [$FFD2] ........ SET1 d.3 62 2 4 d.3 = 1 ........ BBS d.3, r 63 3 5/7 PC+=r if d.3 == 1 ........ CMP A, d 64 2 3 A - (d) N.....ZC CMP A, !a 65 3 4 A - (a) N.....ZC CMP A, (X) 66 1 3 A - (X) N.....ZC CMP A, [d+X] 67 2 6 A - ([d+X]) N.....ZC CMP A, #i 68 2 2 A - i N.....ZC CMP dd, ds 69 3 6 (dd) - (ds) N.....ZC AND1 C, /m.b 6A 3 4 C = C ~(m.b) .......C ROR d 6B 2 4 Right shift (d) as above N.....ZC ROR !a 6C 3 5 Right shift (a) as above N.....ZC PUSH Y 6D 1 4 (SP--) = Y ........ DBNZ d, r 6E 3 5/7 (d)-- then JNZ ........ RET 6F 1 5 POP PC ........ BVS r 70 2 2/4 PC+=r if V == 1 ........ TCALL 7 71 1 8 CALL [$FFD0] ........ CLR1 d.3 72 2 4 d.3 = 0 ........ BBC d.3, r 73 3 5/7 PC+=r if d.3 == 0 ........ CMP A, d+X 74 2 4 A - (d+X) N.....ZC CMP A, !a+X 75 3 5 A - (a+X) N.....ZC CMP A, !a+Y 76 3 5 A - (a+Y) N.....ZC CMP A, [d]+Y 77 2 6 A - ([d]+Y) N.....ZC CMP d, #i 78 3 5 (d) - i N.....ZC CMP (X), (Y) 79 1 5 (X) - (Y) N.....ZC ADDW YA, d 7A 2 5 YA = YA + (d), H on high byte NV..H.ZC ROR d+X 7B 2 5 Right shift (d+X) as above N.....ZC ROR A 7C 1 2 Right shift A high=C, C=low N.....ZC MOV A, X 7D 1 2 A = X N.....Z. CMP Y, d 7E 2 3 Y - (d) N.....ZC RETI 7F 1 6 POP Flags, PC NVPBHIZC SETC 80 1 2 C = 1 .......1 TCALL 8 81 1 8 CALL [$FFCE] ........ SET1 d.4 82 2 4 d.4 = 1 ........ BBS d.4, r 83 3 5/7 PC+=r if d.4 == 1 ........ ADC A, d 84 2 3 A = A+(d)+C NV..H.ZC ADC A, !a 85 3 4 A = A+(a)+C NV..H.ZC ADC A, (X) 86 1 3 A = A+(X)+C NV..H.ZC ADC A, [d+X] 87 2 6 A = A+([d+X])+C NV..H.ZC ADC A, #i 88 2 2 A = A+i+C NV..H.ZC ADC dd, ds 89 3 6 (dd) = (dd)+(d)+C NV..H.ZC EOR1 C, m.b 8A 3 5 C = C EOR (m.b) .......C DEC d 8B 2 4 (d)-- N.....Z. DEC !a 8C 3 5 (a)-- N.....Z. MOV Y, #i 8D 2 2 Y = i N.....Z. POP PSW 8E 1 4 Flags = (++SP) NVPBHIZC MOV d, #i 8F 3 5 (d) = i (read) ........ BCC r 90 2 2/4 PC+=r if C == 0 ........ TCALL 9 91 1 8 CALL [$FFCC] ........ CLR1 d.4 92 2 4 d.4 = 0 ........ BBC d.4, r 93 3 5/7 PC+=r if d.4 == 0 ........ ADC A, d+X 94 2 4 A = A+(d+X)+C NV..H.ZC ADC A, !a+X 95 3 5 A = A+(a+X)+C NV..H.ZC ADC A, !a+Y 96 3 5 A = A+(a+Y)+C NV..H.ZC ADC A, [d]+Y 97 2 6 A = A+([d]+Y)+C NV..H.ZC ADC d, #i 98 3 5 (d) = (d)+i+C NV..H.ZC ADC (X), (Y) 99 1 5 (X) = (X)+(Y)+C NV..H.ZC SUBW YA, d 9A 2 5 YA = YA - (d), H on high byte NV..H.ZC DEC d+X 9B 2 5 (d+X)-- N.....Z. DEC A 9C 1 2 A-- N.....Z. MOV X, SP 9D 1 2 X = SP N.....Z. DIV YA, X 9E 1 12 A=YA/X, Y=mod(YA,X) NV..H.Z. XCN A 9F 1 5 A = (A 4) | (A 4) N.....Z. EI A0 1 3 I = 1 .....1.. TCALL 10 A1 1 8 CALL [$FFCA] ........ SET1 d.5 A2 2 4 d.5 = 1 ........ BBS d.5, r A3 3 5/7 PC+=r if d.5 == 1 ........ SBC A, d A4 2 3 A = A-(d)-!C NV..H.ZC SBC A, !a A5 3 4 A = A-(a)-!C NV..H.ZC SBC A, (X) A6 1 3 A = A-(X)-!C NV..H.ZC SBC A, [d+X] A7 2 6 A = A-([d+X])-!C NV..H.ZC SBC A, #i A8 2 2 A = A-i-!C NV..H.ZC SBC dd, ds A9 3 6 (dd) = (dd)-(ds)-!C NV..H.ZC MOV1 C, m.b AA 3 4 C = (m.b) .......C INC d AB 2 4 (d)++ N.....Z. INC !a AC 3 5 (a)++ N.....Z. CMP Y, #i AD 2 2 Y - i N.....ZC POP A AE 1 4 A = (++SP) ........ MOV (X)+, A AF 1 4 (X++) = A (no read) ........ BCS r B0 2 2/4 PC+=r if C == 1 ........ TCALL 11 B1 1 8 CALL [$FFC8] ........ CLR1 d.5 B2 2 4 d.5 = 0 ........ BBC d.5, r B3 3 5/7 PC+=r if d.5 == 0 ........ SBC A, d+X B4 2 4 A = A-(d+X)-!C NV..H.ZC SBC A, !a+X B5 3 5 A = A-(a+X)-!C NV..H.ZC SBC A, !a+Y B6 3 5 A = A-(a+Y)-!C NV..H.ZC SBC A, [d]+Y B7 2 6 A = A-([d]+Y)-!C NV..H.ZC SBC d, #i B8 3 5 (d) = (d)-i-!C NV..H.ZC SBC (X), (Y) B9 1 5 (X) = (X)-(Y)-!C NV..H.ZC MOVW YA, d BA 2 5 YA = word (d) N.....Z. INC d+X BB 2 5 (d+X)++ N.....Z. INC A BC 1 2 A++ N.....Z. MOV SP, X BD 1 2 SP = X ........ DAS A BE 1 3 decimal adjust for subtraction N.....ZC MOV A, (X)+ BF 1 4 A = (X++) N.....Z. DI C0 1 3 I = 0 .....0.. TCALL 12 C1 1 8 CALL [$FFC6] ........ SET1 d.6 C2 2 4 d.6 = 1 ........ BBS d.6, r C3 3 5/7 PC+=r if d.6 == 1 ........ MOV d, A C4 2 4 (d) = A (read) ........ MOV !a, A C5 3 5 (a) = A (read) ........ MOV (X), A C6 1 4 (X) = A (read) ........ MOV [d+X], A C7 2 7 ([d+X]) = A (read) ........ CMP X, #i C8 2 2 X - i N.....ZC MOV !a, X C9 3 5 (a) = X (read) ........ MOV1 m.b, C CA 3 6 (m.b) = C ........ MOV d, Y CB 2 4 (d) = Y (read) ........ MOV !a, Y CC 3 5 (a) = Y (read) ........ MOV X, #i CD 2 2 X = i N.....Z. POP X CE 1 4 X = (++SP) ........ MUL YA CF 1 9 YA = Y * A, NZ on Y only N.....Z. BNE r D0 2 2/4 PC+=r if Z == 0 ........ TCALL 13 D1 1 8 CALL [$FFC4] ........ CLR1 d.6 D2 2 4 d.6 = 0 ........ BBC d.6, r D3 3 5/7 PC+=r if d.6 == 0 ........ MOV d+X, A D4 2 5 (d+X) = A (read) ........ MOV !a+X, A D5 3 6 (a+X) = A (read) ........ MOV !a+Y, A D6 3 6 (a+Y) = A (read) ........ MOV [d]+Y, A D7 2 7 ([d]+Y) = A (read) ........ MOV d, X D8 2 4 (d) = X (read) ........ MOV d+Y, X D9 2 5 (d+Y) = X (read) ........ MOVW d, YA DA 2 5 word (d) = YA (read low only) ........ MOV d+X, Y DB 2 5 (d+X) = Y (read) ........ DEC Y DC 1 2 Y-- N.....Z. MOV A, Y DD 1 2 A = Y N.....Z. CBNE d+X, r DE 3 6/8 CMP A, (d+X) then BNE ........ DAA A DF 1 3 decimal adjust for addition N.....ZC CLRV E0 1 2 V = 0, H = 0 .0..0... TCALL 14 E1 1 8 CALL [$FFC2] ........ SET1 d.7 E2 2 4 d.7 = 1 ........ BBS d.7, r E3 3 5/7 PC+=r if d.7 == 1 ........ MOV A, d E4 2 3 A = (d) N.....Z. MOV A, !a E5 3 4 A = (a) N.....Z. MOV A, (X) E6 1 3 A = (X) N.....Z. MOV A, [d+X] E7 2 6 A = ([d+X]) N.....Z. MOV A, #i E8 2 2 A = i N.....Z. MOV X, !a E9 3 4 X = (a) N.....Z. NOT1 m.b EA 3 5 m.b = ~m.b ........ MOV Y, d EB 2 3 Y = (d) N.....Z. MOV Y, !a EC 3 4 Y = (a) N.....Z. NOTC ED 1 3 C = !C .......C POP Y EE 1 4 Y = (++SP) ........ SLEEP EF 1 ? Halts the processor ........ BEQ r F0 2 2/4 PC+=r if Z == 1 ........ TCALL 15 F1 1 8 CALL [$FFC0] ........ CLR1 d.7 F2 2 4 d.7 = 0 ........ BBC d.7, r F3 3 5/7 PC+=r if d.7 == 0 ........ MOV A, d+X F4 2 4 A = (d+X) N.....Z. MOV A, !a+X F5 3 5 A = (a+X) N.....Z. MOV A, !a+Y F6 3 5 A = (a+Y) N.....Z. MOV A, [d]+Y F7 2 6 A = ([d]+Y) N.....Z. MOV X, d F8 2 3 X = (d) N.....Z. MOV X, d+Y F9 2 4 X = (d+Y) N.....Z. MOV dd, ds FA 3 5 (dd) = (ds) (no read) ........ MOV Y, d+X FB 2 4 Y = (d+X) N.....Z. INC Y FC 1 2 Y++ N.....Z. MOV Y, A FD 1 2 Y = A N.....Z. DBNZ Y, r FE 2 4/6 Y-- then JNZ ........ STOP FF 1 ? Halts the processor ........
https://w.atwiki.jp/snesspec/pages/149.html
概要 OAM [#oam] 項目フォーマット [#format] パレット [#palette] VRAM上のキャラクタテーブル [#g771f74b] スプライトの優先順位 [#icfc4734] スプライトの描画 [#c56fc8cd] 概要 SNESには128個の独立したスプライトがある。 OAM (Object Attribute Memory) にデータを書き込むことで 表示する画像や座標の設定をする。 OAM OAM全体は544バイトで構成され、 512バイトの下位テーブルと、32バイトの上位テーブルに分けられる。 双方共に128項目を入れることができる。 OAM は 0x2102 レジスタでアクセスするアドレスを決め、 0x2103 のビット 0 でテーブル選択を行い、 0x2104 を通じて書き込むか、もしくは 0x2138 から読み込まれる。 上位テーブルは32バイト分しかなく、0x2102 の下位 4 ビットのみが テーブルのインデックスとして使われる。 内部のOAMアドレスは、スキャンラインの描画中に無効になる。 無効化は決定的に起こるが、どのようにして決定されるのかは分からない。 OAMアドレスに対して何か操作がある瞬間か、 スプライトが現在のスキャンラインに現れる瞬間が 無効化の決定に関係しているのだろうと考えられている。 内部OAMアドレスはブランク強制期間中でない場合、 V-Blank 開始時に 0x2102/0x2103 からリロードされる。 0x2100 のビット 7 が 1 から 0 に変更された時にも リロード処理は発生する。 1バイトの読み込み/書き込み時にアドレスはインクリメントされる。 (内部アドレスは10ビット分あり、ビット9がテーブル選択、 ビット0~8がテーブルのインデックスを表す。) 読み込み動作は、そのまま今のバイトを読み込む。 下位テーブルに対する書き込みは、ワードサイズのバッファに行き、 上位バイトも追加で書き込まれた時に、OAMの適切なワードに書き込まれる。 読み込み、書き込みが交互に起こった場合、ワード値の 上位バイトが書き込みの代わりに読み込まれることになり、 書き込み内容はOAMに反映されなくなる。 このように交互に動作させると、書き込みは上位バイトにのみ行われ、 その上、下位バイトにはゴミデータが書き込まれてしまう。 順を追って説明すると、 OAMを全て0にして始める。 1 を書き込み 読み込み 読み込み 2 を書き込み 読み込み 3 を書き込み この動作の時、 OAM 01 00 00 02 00 03 のようなデータが書き込まれると予想することができるが、実際には OAM 00 00 01 02 01 03 のように書き込まれる。 上位テーブルへの書き込みの方は期待通りに動作する。 項目フォーマット 下位テーブルの1項分目のフォーマットは次のような4バイトで構成される。 OBJ*4+0 xxxxxxxx OBJ*4+1 yyyyyyyy OBJ*4+2 cccccccc OBJ*4+3 vhoopppN 上位テーブルの1項目分のフォーマットは次のような2ビットで構成される。 bit 0/2/4/6 of byte OBJ/4 X bit 1/3/5/7 of byte OBJ/4 s 記号の詳細 Xxxxxxxxx スプライトのX座標。 符号については下記参照。 yyyyyyyy スプライトのY座標。 0 ~ 239 の時は画面内に表示される。 画面から隠れた部分の頭の部分が -1 ~ -63 の位置にある時、 画面の上からスプライトが出現する。 とても大きいサイズのスプライトの場合、 下の端が隠れた時にも画面の上に戻ってくる。 cccccccc スプライトの最初のタイル。 VRAMアドレスの計算方法は下記参照。 これは rrrrcccc とも考えることができ、 16x16 サイズのキャラクタテーブルの行 (row) と列 (column) を指す。 N スプライトのネームテーブル。 VRAMアドレスの計算方法は下記参照。 ppp スプライトのパレット。 最初のパレットの位置は 128 + ppp * 16 oo スプライトの優先順位。 詳細は下記参照。 h/v 水平/垂直反転フラグ。 反転処理は個々のタイルに対してではなく、スプライト全体に及ぶ。 しかし、2つの正方形のスプライトから構成される 長方形のスプライトの場合は、垂直に反転する。 (つまり、"01234567" の行の場合、 "76543210" ではなく、 "32107654" となる) s スプライトのサイズフラグ。 詳細は下記参照。 スプライトのサイズは 0x2101 のビット 5 ~ 7 と OAM の サイズフラグで調節する。 0x2101 では全てのスプライトのサイズを調節する。 OAM サイズフラグが 0 の時は小さい方のサイズが、 1 の時は大きいほうのサイズが選択される。 パレット スプライト用に、16色のパレットが8セット用意されている。 それらは CGRAM のインデックス 128 から始まる。 OAM で指定される ppp は、 (128 + ppp * 16) ~ (128 + ppp * 16 + 15) の範囲を指す。 長方形でないスプライトの場合、パレットの最初のエントリは透明色を表す。 スプライトのパレット 4 ~ 7 は色計算と共有される。 VRAM上のキャラクタテーブル スプライト用に 2 つの 16x16 サイズのキャラクタテーブルが VRAM に用意されている。 これらは BG タイルマップと同じように動作する。 タイル 0x00 は、タイル 0x0F の右側のタイルで、タイル 0xF0 の下側にある。 タイル 0x10 は、タイル 0x00 の下側のタイルで、タイル 0x1F の右側、 タイル 0xFF は、タイル 0xF0 の左側のタイルで、タイル 0x0F の上側にある。 どのキャラクタテーブルを使用するかは OAM の N ビットで設定される。 16x16 のサイズを使って、タイル 0xFF を指定した場合、キャラクタは 0xFF, 0xF0, 0x0F, 0x00 で構成されることになる。 最初に、テーブルは 0x2101 のネームベースビットで指定され、 次に 0x2101 のネームビットでオフセットが指定される。 VRAM 上のスプライトの最初のタイルのワードアドレスは次の式で表される。 ((Base 13) + (cccccccc 4) + (N ? ((Name+1) 12) 0)) 0x7fff キャラクタデータの詳細は BG 参照。 スプライトの優先順位 スプライトには優先順位についての考え方が2種類ある。 1つは OAM の優先順位ビットで、BG に対してスプライトの 表示順位を調整する。詳しくは BG 参照。 もう1つは、スプライト同士の間の表示順位で、 これはスプライトのインデックスと優先順位ローテーションによって調整される。 優先順位ローテーションは 0x2103 のビット 7 でセットする。 このビットが 0 の時、スプライト 0 が最初のスプライトになる。 1 の場合、現在の内部 OAM ワードアドレスから (OAM アドレス無効化処理は影響しない) 、 スプライトに優先順位が設定される (OAMAddr 0xFE) 1 。 0x2102/0x2103 に 0x104 が 4 バイトで書かれた時、 次のフレームでスプライト 3 が優先順位を得る。 しかし、OAM アドレスリセット によって、内部OAMアドレスは 0x104 にリセットされるので、さらに次のフレームでは スプライト 2 が優先順位を得る。 有名な1つの奇妙な動作 0x2102/0x2103 を 0xA に設定した時、 4n+2*(A 1)+1 バイトが書き込まれる。 (例えば、so the next byte written would go to the last byte in the 4-byte sprite record) sprite ((OAMAddr 1)+Y) 0x7F has priority (where Y is the current line as addressed by sprites). Thus, if you put all 128 8x8 sprites at Y=63, write $8000 to $2102/3, then read 3 bytes from $2138, you will see sprites 63-70 having priority on successive scanlines. "最初のスプライト"は、OAM の優先順位ビットの設定に関わらず 他のスプライトよりも前に(一番前に)表示される。 "最初のスプライト" + 1のスプライトは "最初のスプライト" + 2の前に、 "最初のスプライト" + 2のスプライトは "最初のスプライト" + 3の前に表示され、 これは "最初のスプライト" + 127 まで続く。 (127から0にラッピングされる。) 一番前のスプライトのみがBGに対する優先順位を設定できることに注意して欲しい。 "最初のスプライト" + 3 と "最初のスプライト" + 4 は交換可能だが、 "最初のスプライト" + 3 が優先順位 0 、"最初のスプライト" + 4 が優先順位 3 に設定されている時、両方のスプライトがBGの裏に隠されてしまう。 "最初のスプライト" + 4 が BG の前面に来るのが普通の考え方で、 直感に反することのように見えるが、たくさんのゲームがこの挙動に従って動いている。 スプライトの描画 スプライトはスキャンライン毎に描画される。 OBJ が X=256 の時 (X=-256)、X=0 の時と同じように"範囲"と"時間"を考慮する必要がある。 注 実際にX=0に描画するわけではない。 範囲 スキャンライン中の、 "最初のスプライト" から、32 個の最初のスプライトが描画用に選択される。 これらのスプライトは、 -size X 256 に入っている中から選ばれる。 1つのスキャンライン内に 32 個以上のスプライトがあった場合、0x213e のビット 6 がセットされる。 時間 "範囲"の中の最後のスプライトから考えて、8x8 サイズで 34 個のタイルが選択される。 (左から右へ、反転(フリップ)後の) 34 個以上のタイルがあった場合、0x213e のビット 7 がセットされる。 これは、-8 X 256 の範囲の中から選ばれる。 "範囲"と"時間" により、タイルと本当のX座標が決定され、パレットと優先順位を考慮して描かれる。 (X=256,X=-256 のものは X=0 には配置されない。) 詳細は PPU/画面のレンダリング を参照
https://w.atwiki.jp/snesspec/pages/23.html
DMA とは direct memory access の略で、さまざまなコンピュータに搭載されており、 周辺機器とメモリの通信を、CPU を介すことなく行うことができる。 SNES では、DMA の通信中は CPU が一時的にストップする。 HDMA は DMA と似ていますが、こちらは少しのデータを、 スキャンライン毎の H-Blank 期間中に転送する目的で使われる。 HDMA は、表示を乱れさせることなく 1 フレーム中に PPU のレジスタを 操作する時に非常に役立つ。 DMA, HDMA 共にそれぞれ 8 つのチャネル (0 ~ 7) がある。 HDMA は DMA より優先順位が高く、データの転送が重なった場合は、 全ての DMA チャネルが一時停止され、重なった DMA チャネルはその場で停止される。 また、番号が小さいチャネルが優先されて動作する。 DMA DMA には 3 つの動作モードと、いくつかの設定用ビットがある。 方向 (0x43x0 のビット 7) PPUの読み込み/書き込み アドレス固定 (0x43x0 のビット 3) アドレスを調整するかどうか インクリメント (0x43x0 のビット 4) アドレス調整の方向 モード (0x43x0 のビット 0 ~ 2) 下記参照 ポート (0x43x1) ここに xx が指定された時、0x21xx にアクセスする Aアドレス (0x43x2 ~ 0x43x4) CPUアドレス。絶対ロングアドレッシングモード で値を入れる カウント (0x43x5 ~ 0x43x6) 転送バイト数 これらの値は、DMA転送前に設定する必要がある。 0x43x0 のモードビットと転送モードは互いに関係している。 注:1つのレジスタに1度書き込むのと、1つのレジスタに2度書き込むのは同じことが起きる。 2つのレジスタに1度書き込むのと、2つのレジスタにそれぞれ交互に1度ずつ書き込むのも 同じことが起こる。 しかし、2つのレジスタに1度書き込むのと、2つのレジスタにそれぞれ交互に1度ずつ書き込むのは違う。 (訳者注:よく分かりません。) DMAが1バイト転送する間に、マスターサイクルで8クロックの遅延がある。 (FastROM の設定に関係なく) チャネルごとに8クロックの遅延があり、全て転送するまでに12~24の遅延が起こる。 転送プロセス 1バイトを取得して転送先に書き込む DMAは2つのアドレスバスと1つの共有データバスへの優先順位を得ているように見える。 AアドレスはバスAに、ポートはバスBに、それぞれ指定された方向に読み込み/書き込み信号を送る。 1つのバスは「読み込み」に設定され、データがバスに流れる。 もう1つは「書き込み」に設定され、バスのデータが書き込まれる。 PPU/APU/WRAMレジスタはバスBからのみアクセスできる。 これらに対してAアドレスでアクセスしようとすると、オープンバスアクセスの値を返す。 WRAMに対してバスA、バスB (0x2180 ~ 0x2183) の両方を使って アクセスしようとすると失敗する。 0x2180~0x2183 はオープンバス化されている。 また、DMAは 0x4300 ~0x437f、0x420b、0x420cに対してアクセスすることはできない。 書き込みは変化なし、読み込みはオープンバスが返る。 Aアドレスの調整 「アドレス固定」ビットがセットされている時は何もしない。 「インクリメント」ビットがセットされている時は1減算、 セットされていない時は1加算する。 注:バンクバイトは変更されない。 カウント値のデクリメント。0でない場合、1から繰り返す カウント値が最初から0の場合、値がテストされる前に65535にラップされ、 これにより、65536バイトが転送される。 注:カウント値 (0x43x5 ~ 0x43x6) は通常0になるまで繰り返されるが、 HDMAと衝突した場合、転送は途中で中止 (terminate) される。 HDMA HDMAには4つのフラグと、5つの設定項目がある。 (*) の付いている項目はHDMAの転送前にセットする必要があり、 (+) の付いている項目はHDMAの転送が始まったフレーム中に変更する必要がある。 (*) アドレッシングモード (0x43x0 のビット 6) 0 = 直接, 1 = 間接 (*) 転送モード (0x43x0 のビット 0~2) 下記参照 (*) ポート (0x43x1) DMAと同じ (*) Aアドレス (0x43x2 ~0x43x4) HDMAテーブルへのポインタ。 必ずしも転送中のフレームに変更する必要はないが、次の転送前に停止するためには変更する必要がある。 間接アドレス (0x43x5 ~ 0x43x6) 間接バンクと一緒に使用。下記参照。 (*) 間接バンク (0x43x7) 間接アドレスと一緒に使用。下記参照。 (+) アドレス (0x43x8 ~ 0x43x9) 下記参照。 (+) 繰り返し (0x43xA のビット 7) 全てのスキャンラインに書き込むかどうか (+) 行カウンタ (0x43xA のビット 0~6) 下記参照。 転送実行フラグ(DoTransfer) 内部的に使用。 モード値はDMAと同じだが、スキャンライン毎に1度だけ実行される。 One Register Write Once モードはスキャンライン毎に1バイトだけ、 One Register Write Twice モードではスキャンライン毎に2バイト書き込まれる。 スキャンライン毎にHDMAがアクティブになる度に (つまり、そのフレームで少なくとも1つは停止も終了もされていない時)、 マスターサイクルで~18のオーバーヘッドがかかる。 それぞれのチャネルは転送が実際に起こった場合、 スキャンラインごとに追加で8のオーバーヘッドがかかる。 (たぶんテーブルから0x42xAに値がロードされているだろう) 間接アドレスが変更される場合、ロード時に 16のマスターサイクルが必要になる。 そして、1バイトの転送ごとに8サイクルかかる。 結果として、HDMAはスキャンラインごとにマスターサイクルで 合計466サイクルの時間を必要とする。 (8チャネル全てがアクティブ、間接アドレスの変更、4バイトの転送が全て同時に起こった場合) HDMAの動作には2つの段階があり、 最初の段階はフレーム開始時に (V(垂直)=0, H(水平)=約6)、 全てのアクティブなHDMAチャネルに対して発生する(0x420c 参照)。 「アドレス」値に、Aアドレスがコピーされる テーブルから 0x43xA に対して値をロードする (0x00 をロードすると、その場でチャネルを停止する…だろう) 必要なら、間接アドレスをロードする 転送実行フラグ(DoTransfer) をTrueにする CPUはこの動作の間停止される。 マスターサイクルで~18のオーバーヘッドがあり、 それぞれのチャネルが、直接モードのHDMAチャネルにセットされている時は8サイクル、 間接モードのHDMAチャネルにセットされている時は24サイクルが追加で必要となる。 フレーム開始後にHDMAを開始させた場合は基本的に、 間接モードチャネル用に 0x43x8 ~ 0x43xA、0x43x5 ~ 0x43x6 を使って 手動で初期化プロセスを実行する必要がある。 次のステップの4段階目の最初の1回は転送が行われないので注意すること。 それから、フレーム中にチャネルがすでに停止されていた場合、再スタートすることはできない。 (もしくはチャネルを有効にした時に4段階目が自動的に実行されてしまう??) V=0 から V=0xe0 (オーバースキャンが有効の場合、V=0xef) の H=0x116 くらいの時に次の動作が始まる。 転送実行フラグ(DoTransfer) が False の場合、3段階目へ この転送モードの時、1か2か4バイトが必要 アドレス/間接アドレスのいずれかから1バイト読み込み、インクリメントする。 ポートに1バイト書き込む。Port+1, Port+2, Port+3 も、転送モードによっては書き込む。 DMAの時と同じように、0x2180 を通じてPPU から PPU、RAM から RAMに転送する時は注意が必要。 0x43xA をデクリメント 転送実行フラグ(DoTransfer) に「繰り返し」ビットと同じ値をセット 行カウンタが0の場合 「アドレス」から次の1バイトを読み込み、0x43xA に入れる(行番号と繰り返しも同じようにする)。 間接アドレスモードの時、「アドレス」から2バイト読み込み、「間接アドレス」に入れ、 「アドレス」の値を2バイト分インクリメントする。 注(奇妙な動作):0x43xA が 0 で、処理中のチャネルが現在の行で最後のHDMAチャネルだった場合、 「アドレス」から1バイトのみ読み込まれ、下位バイトには0x00が適用される。 「アドレス」は1つだけインクリメントされ、1少ないCPUサイクルが消費される。 0x43xA が0の時、処理中のHDMAチャネルのこのフレームでの転送は終了する。 0x420c のビットはクリアされないが、次のフレームには自動的に開始される。 転送実行フラグ(DoTransfer) をTrueにする 次のスキャンラインで1段階目から繰り返す HDMAはV-Blank期間中は起こらない。 画面エフェクトは何も起こらないだろう。 フレーム開始時、(V-Blankの終了時)にアクティブなチャネルはリセットされる。 V-Blank中にHDMAレジスタを更新することで、 書き込み直後に転送されたり、PPUの状態を意図せず変更してしまったり というような、厄介な挙動を避けることができる。 今までHDMAテーブルというものが暗黙的に使われてきたが、 これは項目の配列を指し、行番号と繰り返しフラグから始まる。 繰り返しフラグがFalseの時、1スキャンライン分のデータと、 次の項目が始まる前までの行番号の入ったカウント値が続く。 繰り返しフラグがTrueの時、複数のスキャンラインのデータが続く。 このデータは、ポインタ値(間接HDMA)か即値(直接HDMA)を指す。 以上のことから、フレーム処理中にHDMAを開始する時に なぜ手動で「アドレス」、「繰り返し」、「行番号」を初期化しないと いけないのかが見えてくると思う。 これらはフレーム開始時に初期化されている。 「アドレス」、「繰り返し」、「行番号」はHDMAによって変更されるが、 「Aアドレス」は変更されないことに注意して欲しい。
https://w.atwiki.jp/snesspec/pages/104.html
REP (Reset Status Bits) [ステータスビットのリセット] オペランドで指定した値で、1 になっているビットを ステータスフラグで 0 にする。 ステータスフラグのビット 5 をクリアする例 REP #%00100000 ; ビット 5 のクリア 複数のビットをクリアする例 REP #%10110000 ; ビット 7, 5, 4 をクリア フラグ変化 nvmxdizc オペランドで指定された値でセットされているフラグはクリアされる。 それ以外のフラグは変化なし。 コード一覧 アドレッシングモード 文法 オペコード バイト数 命令サイクル Immediate REP #const C2 2 3
https://w.atwiki.jp/snesspec/pages/234.html
SLEEP コード一覧 文法 オペコード バイト数 命令サイクル フラグ変化 内容 SLEEP EF 1 3 -------- standby SLEEP mode
https://w.atwiki.jp/snesspec/pages/237.html
0x2100 - INIDISP (スクリーン初期化) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x - - - b b b b x ブランク強制 (0 = オフ、 1 = オン) bbbb 画面の輝度 (0 = オフ、0x0F = 最大) ブランク強制フラグはスキャンライン中にも無効にできる。 しかし、ブランク強制中は内部のレンダリングバッファが更新されないので、 そのスキャンラインの表示は乱れる。 今のところ、BG はタイルのいくつかが乱れ (PPU の処理がどれほどの時間続くのかによる)、 スプライトの表示はスキャンライン中ずっと乱れるものと考えられている。 V-Blank の最初の行でこのレジスタに書き込んだ時 (225 か 240。オーバースキャンフラグの設定による)、 ブランク強制はアクティブになり、OAM アドレスのリセットが起こる。 0x2101 - OBJSEL (スプライトサイズ・データ領域選択) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 s s s n n b b b sss スプライトサイズ 000 8x8 または 16x16 001 8x8 または 32x32 010 8x8 または 64x64 011 16x16 または 32x32 100 16x16 または 64x64 101 32x32 または 64x64 110 16x32 または 32x64 (ドキュメントに載っていない) 111 16x32 または 32x32 (ドキュメントに載っていない) nn ネーム選択 bbb ネーム基底アドレス選択 実アドレスは bbb x 0x2000 (8KB) 0x2102 - OAMADDL (OAM下位アドレス) アクセスフラグ 書下強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a a a 0x2103 - OAMADDH (OAM上位アドレスとスプライト優先順位) アクセスフラグ 書上強V?- D7 D6 D5 D4 D3 D2 D1 D0 p - - - - - - b p スプライト優先度設定フラグ このフラグがセットされている時、0 以外のスプライトは優先度を得る。 b aaaaaaaa OAM アドレス この値は OAM に対して、2 つの考え方で考えることができる。 OAM が 544 バイトの単一のテーブルで構成されると考えた場合、 baaaaaaaa はこのテーブルのワードアドレスを指す。 OAM が 512 バイトと 32 バイトのテーブルで構成されると考えた場合、 b の値はテーブルのセレクタとして、aaaaaaaa は選択されたテーブルの ワードアドレスを指す。 スキャンラインが描画中の場合、 内部 OAM アドレスは無効化される。 この無効化は決定的に起こる。 どのように決定されるかは不明。 ブランク強制期間でない場合、これら 0x2102, 0x2103 のレジスタに最後に書かれた値が V-Blank 開始時に内部 OAM アドレスにリロードされる。 これは "OAM リセット" と呼ばれている。 OAM リセットは、0x2100 に値を書き込んだ時にも起こる。 0x2102 か 0x2103 に値を書き込んだ場合、 全ての内部 OAM アドレスが、最後にこのレジスタに書き込まれた値にリセットされる。 例えば、 このレジスタから 0x104 を書き込んだ後 4 バイトの値を書き込み、 0x2103 に 1 をセットすると、OAM アドレスは 6 ワード目ではなく、 4 ワード目を指す。 0x2104 - OAMDATA (OAMデータ書き込み) アクセスフラグ 書バ強V-- D7 D6 D5 D4 D3 D2 D1 D0 d d d d d d d d OAM に対する書き込みは、変わった方法で行われる。 ワード値の上位バイトが書き込まれるまで、OAM の下位テーブルは影響を受けない。 (しかし、上位テーブルはすぐに内容が反映される。) アドレスをセットした後、書き込み/読み込みを交互に行った場合、 OAM は上位テーブルにのみ影響を受ける。 例えば、 アドレスを 0 にセット 1 を書き込み 2 を書き込み 読み込み 3 を書き込み と順番に実行すると、 想像通りに "01 02 xx 03" という内容にはならず、 実際には "01 02 01 03" となる。 技術的にはこのレジスタに対して H-Blank 中にも値が書き込めそうに見えるが、 "OAM アドレス無効化" が起こっており、OAM への書き込みは思うように反映されない。 しかしブランク強制期間中には書き込むことができ、 V-Blank の間か、もしくは(たぶん)強制ブランク中に 0x2102 ~ 0x2103 のリセットが行われたときに書き込むことができる。 0x2105 - BGMODE (BGモード・キャラクタサイズ設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 D C B A e m m m A/B/C/D BG キャラクタサイズ (BG1/BG2/BG3/BG4) 1 の時、16x16 タイルが、 0 の時、8x8 タイルがそれぞれ使われる。 しかし、モード 5・6 の時は常に 16x16 タイルが使われ、 モード 7 の時は常に 8x8 タイルが使われる。 mmm BG モード e モード 1 の BG3 の優先度フラグ モード BG深度 OPT 優先度 1 2 3 4 前面 → 背面 0 2 2 2 2 n 3AB2ab1CD0cd 1 4 4 2 n 3AB2ab1C 0c C3AB2ab1 0c (e が 1 の時) 2 4 4 y 3A 2B 1a 0b 3 8 4 n 3A 2B 1a 0b 4 8 2 y 3A 2B 1a 0b 5 4 2 n 3A 2B 1a 0b 6 4 y 3A 2 1a 0 7 8 n 3 2 1a 0 7拡張BG 8 7 n 3 2B 1a 0b "OPT" は、タイル毎オフセットモード (Offset-per-tile mode) を意味する。 優先度の数字は、その数字の優先度が与えられたスプライトを指す。 アルファベットは BG を指し (A=1, B=2 ...)、大文字が優先度 1、 小文字が優先度 0 を表す。 モード 7 の拡張 BG モードは、 BG2 を有効にすることを指し、 BG2 は BG1 と同じタイルマップとキャラクタデータを使用するが、 ピクセルデータのビット 7 は優先度ビットとして使われる。 BG2 は、下記の BG毎のレジスタで変わった動作をする。 詳細は BG (背景) のモード 7 の項目を参照。 0x2106 - MOSAIC (モザイク表示用サイズ・スクリーン設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 x x x x D C B A A/B/C/D BG1/BG2/BG3/BG4 (1=有効, 0=無効) xxxx ピクセルサイズ (0=1x1, F=16x16) モザイクフィルターは、画面を 縦X, 横X のサイズの正方形で分割する。 正方形内の一番左上のピクセルで正方形が塗りつぶされる。 この正方形の一番上のラインを "開始ライン" とすると、 フレーム描画中にこのレジスタを設定する時、 "開始ライン" は、描画中のスキャンラインを指す。 フレーム描画中でない場合、"開始ライン" はフレームの 一番上のラインを指す。 例えば、偶数のラインが全て赤で、奇数のラインが全て青の場合、 フレーム処理中に xxxx = 1 を指定すると、 現在のスキャンラインの位置によって、画面が赤で塗りつぶされるか、 もしくは青で塗りつぶされることになる。 このレジスタに、同じ値を書き込んでも "開始ライン" はリセットされない。 モザイクはスクロール処理後、クリッピング・ウインドウ・ カラーウインドウ・計算の前に適用される。 縦X、 横X のブロックの1部分をクリッピングすることができ、 モザイクのかかっていないBGのように、計算を入れることもできる。 しかし、スクロール処理は1部分だけに入れるようなことはできない。 モード 5/6 はハーフサイズのピクセルを2倍に拡大しなければならない。 xxxx=0 を指定した時にも画面の変更が行われ、 偶数列のハーフサイズピクセル (通常サブスクリーンにある) は、 奇数列のハーフサイズピクセルを隠してしまう。 インターレスモードの時、同じことが垂直方向にも起こる。 モード 7 の場合には、モード 7 の変形処理が 縦X横X のブロックに 何も変化を与えないことから、BG1 のモザイク処理は通常通り行われる。 BG2 の場合、このレジスタのビット A は垂直モザイクを、 ビット B は水平モザイクを表す。 これにより、縦1横X, 縦X横1, 縦X横X ブロックを使うように設定が拡張される。 BG1 はビットAによりXサイズのブロックで表示され、 BG2 の高優先度に設定されているピクセルは 横1縦X に拡張されて BG1 の前に表示されるので、面白い画面処理を行うことができる。 0x2107 - BG1SC (BG1タイルマップアドレスとサイズ) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a y x aaaaaa BG のタイルマップアドレス (addr 10) aaaaaa x 0x0800 (2KB) x/y タイルマップ水平/垂直ミラー 00 32x32 01 64x32 10 32x64 11 64x64 全てのタイルマップは 32x32 のタイルで構成される。 x と y が両方 0 の場合、1 つのタイルマップアドレスのみが存在する。 x が 1 の場合、2 つ目のタイルマップが 1 つ目の後に続き、 2 番目は 1 番目の右側に配置される。 y が 1 の場合、2 つ目のタイルマップが 1 つ目の後に続き、 2 番目は 1 番目の下側に配置される。 両方が 1 の場合、2 つ目は右側に、3 つ目は下側、 4 つ目は右下に配置される。 0x2108 - BG2SC (BG2タイルマップアドレスとサイズ) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a y x 0x2109 - BG3SC (BG3タイルマップアドレスとサイズ) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a y x 0x210A - BG4SC (BG4タイルマップアドレスとサイズ) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a y x 0x210B - BG12NBA (BG1,BG2キャラクタデータ領域設定) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 b b b b a a a a aaaa = BG1 のベースアドレス (addr 13) aaaa x 0x2000 (8 KB) bbbb = BG2 のベースアドレス (addr 13) bbbb x 0x2000 (8 KB) 0x210C - BG34NBA (BG3,BG4キャラクタデータ領域設定) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 b b b b a a a a aaaa = BG3 のベースアドレス (addr 13) aaaa x 0x2000 (8 KB) bbbb = BG4 のベースアドレス (addr 13) bbbb x 0x2000 (8 KB) 0x210D - BG1HOFS, M7HOFS (BG1水平スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 BG1HOFS x x x x x x x x - - - - - - x x D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 M7HOFS m m m m m m m m - - - m m m m m x BG オフセット (10 ビット) m モード 7 の BG オフセット (13 ビット、符号は 2 の補数表現) 2 種類のレジスタが 1 つに収まっている。 (4 つが 2 つに収まっているとも言える?) 0x210d への書き込みは、0x210f ~ 0x2114 へと続くレジスタの、 BGnxOFS と同じようにも動くし、 0x211b ~ 0x2120 へと続く M7* レジスタの、 M7HOFS として一緒に動作させることもできる。 モード 0 ~ 6 では、BG1xOFS を使い、M7xOFS は無視される。 モード 7 では M7xOFS を使い、BG1xOFS は無視される。 BG1HOFS と M7HOFS では、レジスタに入れる内容が異なる。 0x210E - BG1VOFS, M7VOFS (BG1垂直スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 BG1VOFS x x x x x x x x - - - - - - x x D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 M7VOFS m m m m m m m m - - - m m m m m 0x210F - BG2HOFS (BG2水平スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2110 - BG2VOFS (BG2垂直スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2111 - BG3HOFS (BG3水平スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2112 - BG3VOFS (BG3垂直スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2113 - BG4HOFS (BG4水平スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2114 - BG4VOFS (BG4垂直スクロール量) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - x x 0x2115 - VMAINC (ビデオポート調整) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 i - - - m m i i i アドレスインクリメントモード 0 = 0x2118 への書き込み / 0x2139 からの読み込み後にインクリメント 1 = 0x2119 への書き込み / 0x213a からの読み込み後にインクリメント 0x2118, 0x2119 を通じて 1 ワードを書き込む時、 下位バイトを先に書き、上位バイトを後で書き込む。 1 を書き込む方が都合が良いだろう。 ii アドレスインクリメント量 00 = 普通に 1 インクリメント 01 = 32 インクリメント 10 = 128 インクリメント 11 = 128 インクリメント mm アドレスリマップ (address remapping) 00 = 再配置無し 01 = aaaaaaaaBBBccccc = aaaaaaaacccccBBB のようにリマップ 10 = aaaaaaaBBBcccccc = aaaaaaaccccccBBB のようにリマップ 11 = aaaaaaBBBccccccc = aaaaaacccccccBBB のようにリマップ リマップ は、アドレス変換時に実行される。 0x2116 ~ 0x2117 が #$0003 にセットされている時、ワードアドレス #$0018 が 代わりに書き込まれ、0x2116 ~ 0x2117 は 0x0004 にインクリメントされる。 0x2116 - VMADDL (VRAMアドレス (下位)) アクセスフラグ 書下強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a a a 0x2117 - VMADDH (VRAMアドレス (上位)) アクセスフラグ 書下強V?- D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a a a 0x2118 ~ 0x2119 と 0x2139 ~ 0x213a 用のアドレスをセットする。 バイトアドレスではなく、ワードアドレスであることに注意。 0x2118 - VMDATAL (VRAMデータ書き込み (下位)) アクセスフラグ 書下強V-- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2119 - VMDATAH (VRAMデータ書き込み (上位)) アクセスフラグ 書下強V-- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x VRAM にデータを書き込みます。 インクリメントが実行される前に、書き込んだ値がすぐに (?) 適用される。 アドレスは、2 バイト中のどちらか 1 バイトが書き込まれた時にインクリメントする。 どちらを書き込んだ時にインクリメントされるかは、 0x2115 のビット 7 の設定に関連している。 0x2115 のアドレス変換ビットも気に留めておくこと。 0x2139 ~ 0x213a とこのレジスタの相互作用については不明。 0x211A - M7SEL (画面モード7初期化) アクセスフラグ 書バ強V?- D7 D6 D5 D4 D3 D2 D1 D0 r c - - - - y x r プレイ画面サイズ 0 の時、プレイ画面は 1024x1024 に設定される (タイルマップは完全に塗りつぶされる)。 1 の時、プレイ画面はさらに大きくなり、空き領域の塗りつぶしを行う。 c ビット 7 セット時の空き領域塗りつぶし 0 = 透明 1 = キャラクタ 0 で塗りつぶし モード 7 の他のタイルのように、塗りつぶし処理は行列変換される。 x/y 水平/垂直ミラー ビットがセットされている時、 256x256 ピクセルのスクリーンは反転される。 0x211B - M7A (Mode7拡大縮小回転用マトリックスA) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 a a a a a a a a a a a a a a a a 0x2134 ~ 0x2136 と一緒に使う。 0x211C - M7B (Mode7拡大縮小回転用マトリックスB) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 a a a a a a a a a a a a a a a a 0x2134 ~ 0x2136 と一緒に使う。 0x211D - M7C (Mode7拡大縮小回転用マトリックスC) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 a a a a a a a a a a a a a a a a 0x211E - M7D (Mode7拡大縮小回転用マトリックスD) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 a a a a a a a a a a a a a a a a これらは 2 度書きレジスタで、下位バイトを先に書き込み、 上位バイトをその後書き込む。 これらのレジスタへの書き込みは、次のように動作すると考えられている。 Reg = (Current 8) | Prev; Prev = Current; Prev は 1 つしか存在せず、これらレジスタ全てで共有される。 Prev は BGnxOFS レジスタでは共有されないが、 M7xOFS レジスタでは共有される。 これらは、モード 7 の行列パラメータを指定する。 値は 8 ビットの固定小数点表現である。 つまり、セットされた値は 256.0 で割り算される。 0x2134 ~ 0x2136 レジスタから、 A * (B 8) の値が読み込まれる。 これには、それほど大きな遅延は発生しない。 モード 7 レンダリング中には動作しないだろう。 0x211F - M7X (Mode7中央位置X) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB Dx D9 D8 x x x x x x x x x x x x x x x x 0x2120 - M7Y (Mode7中央位置Y) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB Dx D9 D8 x x x x x x x x x x x x x x x x これらは、 M7A ~ M7D と同じように 2 度書きレジスタで、 値は 2 の補数表現になる。 行列変換の式 [ X ] [ A B ] [ SX + M7HOFS - CX ] [ CX ] [ ] = [ ] * [ ] + [ ] [ Y ] [ C D ] [ SY + M7VOFS - CY ] [ CY ] SX/SY はスクリーンの座標。 X/Y はプレイ中の画面から得られるピクセルの座標。 0x211a のビット 7 がクリアされている場合、 結果は 0 =X =1023 と 0 =Y =1023 の範囲に制限される。 0x211a のビット 6 と 7 が両方セットされていて、 X か Y が 0 より小さいか、 1023 より大きい場合、 それぞれの下位 3 ビットはキャラクタ 0 からピクセルが選択される。 ビット精度を考慮した式 #define CLIP(a) (((a) 0x2000)?((a)|~0x3ff) ((a) 0x3ff)) X[0,y] = ((A*CLIP(HOFS-CX)) ~63) + ((B*y) ~63) + ((B*CLIP(VOFS-CY)) ~63) + (CX 8) Y[0,y] = ((C*CLIP(HOFS-CX)) ~63) + ((D*y) ~63) + ((D*CLIP(VOFS-CY)) ~63) + (CY 8) X[x,y] = X[x-1,y] + A Y[x,y] = Y[x-1,y] + C (全ての場合で、X[], Y[] は 8 ビットの固定小数点表現) 0x2121 - CGADD (CG-RAM書き込みアドレス) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 c c c c c c c c ワードアドレス (色) をセットする。 指定されたアドレスにデータを書き込む時には 0x2122 を通して、 読み込む時には 0x213b を通して行う。 0x2122 - CGDATA (CG-RAMデータ書き込み) アクセスフラグ 書ワ強VH- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB Dx D9 D8 g g g r r r r r - b b b b b g g CGRAM にデータを書き込む。 このレジスタに書き込んだ値は、パレットの色に設定される。 CGRAM へのアクセス処理は、OAM の下位テーブルのようにして行う。 詳細は 0x2104 参照。 色の値は、 BGR の順で扱われる。 0x2123 - W12SEL (BG1,BG2ウィンドウマスク設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 A B C D a b c d c ウインドウ 1 有効 (BG1) a ウインドウ 2 有効 (BG1) C ウインドウ 1 有効 (BG2) A ウインドウ 2 有効 (BG2) 1 の時、指定されたウインドウと BG が紐付けされる。 (0x212e ~ 0x212f の設定参照) d ウインドウ 1 反転 (BG1) b ウインドウ 2 反転 (BG1) D ウインドウ 1 反転 (BG2) B ウインドウ 2 反転 (BG2) 0x212a ~ 0x212b の、表示領域の組み合わせ式で、 W が ~W (not W) になる。 0x2124 - W34SEL (BG3,BG4ウィンドウマスク設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 A B C D a b c d c ウインドウ 1 有効 (BG3) a ウインドウ 2 有効 (BG3) C ウインドウ 1 有効 (BG4) A ウインドウ 2 有効 (BG4) 1 の時、指定されたウインドウと BG が紐付けされる。 (0x212e ~ 0x212f の設定参照) d ウインドウ 1 反転 (BG3) b ウインドウ 2 反転 (BG3) D ウインドウ 1 反転 (BG4) B ウインドウ 2 反転 (BG4) 0x212a ~ 0x212b の、表示領域の組み合わせ式で、 W が ~W (not W) になる。 0x2125 - WOBJSEL (スプライトウィンドウマスク設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 A B C D a b c d c ウインドウ 1 有効 (OBJ) a ウインドウ 2 有効 (OBJ) C ウインドウ 1 有効 (Color) A ウインドウ 2 有効 (Color) 1 の時、指定されたウインドウと BG が紐付けされる。 (0x212e ~ 0x212f の設定参照) d ウインドウ 1 反転 (OBJ) b ウインドウ 2 反転 (OBJ) D ウインドウ 1 反転 (Color) B ウインドウ 2 反転 (Color) 0x212a ~ 0x212b の、表示領域の組み合わせ式で、 W が ~W (not W) になる。 注 OBJ = スプライト Color = カラーウインドウ 0x2126 - WH0 (ウィンドウ1左座標設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x ウインドウ 1 の左端の座標を設定する。 注 左端が右端より大きい場合、ウインドウは設定されない。 0x2127 - WH1 (ウィンドウ1右座標設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x ウインドウ 1 の右端の座標を設定する。 注 左端が右端より大きい場合、ウインドウは設定されない。 0x2128 - WH2 (ウィンドウ2左座標設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x ウインドウ 2 の左端の座標を設定する。 注 左端が右端より大きい場合、ウインドウは設定されない。 0x2129 - WH3 (ウィンドウ2右座標設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x ウインドウ 2 の右端の座標を設定する。 注 左端が右端より大きい場合、ウインドウは設定されない。 0x212A - WBGLOG (BGウインドウマスクロジック設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 4 4 3 3 2 2 1 1 0x212B - WOBJLOG (スプライトウインドウマスクロジック設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 - - - - c c o o 44/33/22/11/oo/cc マスクロジック (BG1/BG2/BG3/BG4/OBJ/Color) ウインドウの組み合わせロジックをブールで指定する。 00 = OR 01 = AND 10 = XOR 11 = XNOR Consider two variables, W1 and W2, which are true for pixels between the appropriate left and right bounds as set in $2126-$2129 and false otherwise. Then, you have the following possibilities (replace "W#" with "~W#", depending on the Inversion settings of $2123-$2125) Neither window enabled = nothing masked. One window enabled = Either W1 or W2, as appropriate. Both windows enabled = W1 op W2, where "op" is as above. Where the function is true, the BG will be masked. See the section "WINDOWS" below for more details. 0x212C - TM (メインスクリーン指定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 - - - o 4 3 2 1 1/2/3/4/o メインスクリーンに表示 BG1/BG2/BG3/BG4/OBJ 0x212D - TS (サブスクリーン指定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 - - - o 4 3 2 1 1/2/3/4/o サブスクリーンに表示 BG1/BG2/BG3/BG4/OBJ 0x212E - TMW (メインスクリーンウインドウマスク指定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 - - - o 4 3 2 1 1/2/3/4/o メインスクリーンに指定するウインドウマスク BG1/BG2/BG3/BG4/OBJ 0x212F - TSW (サブスクリーンウインドウマスク指定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 - - - o 4 3 2 1 1/2/3/4/o サブスクリーンに指定するウインドウマスク BG1/BG2/BG3/BG4/OBJ 0x2130 - CGSWSEL (色追加選択) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 c c m m - - s d cc 計算前の黒にクリッピングする色 00 = 無し 01 = ウインドウの外側の色のみ 10 = ウインドウの内側の色のみ 11 = 常に mm 色計算防止 00 = 無し 01 = ウインドウの外側の色のみ 10 = ウインドウの内側の色のみ 11 = 常に s サブスクリーン追加 (固定色の変わりに) d 256色のBG用ダイレクトカラーモード 0x2131 - CGADSUB (色計算指定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 s h b o 4 3 2 1 s 加算/減算の選択 0 = 加算 1 = 減算 h ハーフカラーマス 1 の時、カラーマスの結果は 1 / 2 になる。 (0x2130 のビット 1 がセットされていて固定色が使われている時、 または色がクリッピングされている時は除く) 4/3/2/1/o/b カラーマス有効 BG1/BG2/BG3/BG4/OBJ/背景 (Backdrop) 0x2132 - COLDATA (固定色のデータ) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 b g r c c c c c b/g/r 輝度を設定する色 ccccc 輝度 画面をオレンジで塗りつぶす時 LDA #$3f STA $2132 LDA #$4f STA $2132 LDA #$80 STA $2132 0x2133 - SETINI (スクリーンモード/ビデオ設定) アクセスフラグ 書バ強VH- D7 D6 D5 D4 D3 D2 D1 D0 s e - - p o I i s 外部同期 "sfx" グラフィックスのスーパーインポーズに使用します。 通常は 0 です。このビットについて他に分かることはありません。 SPPU1 チップには "EXTSYNC" (または not-EXTSYNC) というピンがあり、 これは Vcc に繋げられています。 e モード 7 拡張BG このビットがセットされている時、モード 7 の BG2 が有効になります。 BG2は、BG1と同じタイルとキャラクタデータを使用しますが、 色データの上位ビットは、ピクセルの優先順位として解釈されます。 様々なところで、このビットがビット 7 にも関連している 可能性があると報告されています。 例えば、「外部LSIからのデータ供給有効」というようなものです。 これはもちろん勘違いだと思います。 p 擬似ハイレゾモード有効 サブスクリーンから(ゼロベースで)偶数番号のピクセルを、 メインスクリーンから奇数番号のピクセルを取得することで 水平方向に512ピクセルの解像度を作ります。 カラーマスはモード5/6の時と同じように動作します。 インターレスビットは影響を受けません。 モザイクは通常通り動作します(モード5/6のようにではなく)。 ウインドウによってサブスクリーンはクリッピングされ、 メインスクリーンの左側もクリッピングされます。 右側は想像通りにはクリッピングされません。 ピクセル列 0 はどうなるのか分かりません。 モード 5/6 の時にこのビットをセットしても変更はありません。 o オーバースキャンモード 1の時、通常の 224 行に代わって、239 行が画面に表示されます。 これは、V-Blank の開始が遅れることと、期間が短くなることを意味します。 スクリーンに追加された行はTVに表示されますが、 8ピクセル分上に移動します。 I OBJ インターレス 1の時、BGモードに関係なく、OBJがインターレスモードになり、 半分の高さで表示されます。(ビット 0 参照) これは、OBJが通常通り描画されるかそうでないかだけを設定します。 TVに対するインターレス信号の出力は下記のビット 0 で指定します。 i スクリーンインターレス 1の時、モード 5 (多分6も) の BG の スクリーンが 224 (または 239) ではなく、 448 (または 478) ピクセルになります。 他のモードでこのフラグをセットすると、1 ピクセルずつ飛び飛びに表示されます。 タイルマップのそれぞれの項目は、位置を変えることで 高くなったスクリーンを表現します。 (擬似ハイレゾモードのような動作) また、ハードウェアの方は、 SNES の画面を 普通のインターレス信号で出力するようになります。 オーバースキャンフラグについての注意: 通常の NMI トリガーポイントの前に、これを 0xE0 (224) 行に変更した場合、 フレーム中ずっとこれを設定したような意味になってしまいます。 これは NMI トリガーポイントとHDMA の停止に影響します。 (訳注:NMIトリガーについて調べた後、もっかいきちんと読んで修正します。) 一番初めの方のスキャンライン "X" (0xE1 = X = 0xF0) でオーバースキャンを 0 にすると、 NMI が X 行で発生し、最後の HDMA 転送が X-1 行で起こります。 表示領域は普通のオーバースキャンでないモードと同じ 0xE1 ~ 0xEC の位置に残り、 0xED の1ピクセルだけ上の位置に移動します。 そして、0xEF ~ 0xF4 で 垂直同期を失います。 行 0xE1 (225) でフラグをオンにした場合、 NMI が 0xE2 (226) 行で発生し、 0xE0 行で起こった最後のHDMAがまだ発生している。 いつでもフラグをオフにした時には他に何かが起こるが、 スキャンラインの開始から十分時間が経過した後では 何も起こらない。 何も画面変化が起こらない場合でも、 オーバースキャンの設定はVRAMの書き込みに影響を及ぼす。 0xE1(225) ~ 0xF0(240) の間に、 以下のようなコードを実行すると、 LDA # - STA $2118 LDA r2133 STA $2133 LDA # + STA $2118 オーバースキャンフラグが 0 か、 1 かによって、 VRAMには + のみ、または - のみが書き込まれる。 0x2134 - MPYL (乗算結果の下位) アクセスフラグ 読下強VH? D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2135 - MPYM (乗算結果の中位) アクセスフラグ 読中強VH? D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2136 - MPYH (乗算結果の上位) アクセスフラグ 読上強VH? D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x これらは、0x211b に書き込まれた 2 つの 16 ビット値の積と、 0x211c に最後に書き込まれた 8 ビットの値が入る。 さほど大きな遅延は発生しない。 モード 7 のレンダリング中にはたぶん使えない。 0x2137 - SLHV (H/V カウンタのソフトウェアラッチ) アクセスフラグ バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - - - 読み込み時、0x4201 のビット 7 がセットされている時、 H/V カウンタ (0x213c と 0x213d) が現在の X, Y 座標でラッチされる。 読み込みデータは、オープンバスの値を返す。 0x2138 - OAMDATAREAD (OAM データ読み込み) アクセスフラグ 読ワ強V?- D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2102 ~ 0x2103 で現在のアドレスを選択する。 アドレス値は、読み込み時にインクリメントされる。 0x2104 へ書き込んだ値を返す。 0x2104 と スプライト 参照。 OAMアドレス無効化は、このレジスタ操作によるアドレス読み込みでも 発生するかもしれない。 0x2139 - VMDATAL (VRAM データ読み込み(下位)) アクセスフラグ 読下強V?- 7 6 5 4 3 2 1 0 x x x x x x x x 0x213A - VMDATAH (VRAM データ読み込み(上位)) アクセスフラグ 読上強V?- 7 6 5 4 3 2 1 0 x x x x x x x x これらは、単純にVRAMのデータを読み込む時に使用する。 0x2115 のビット 7 に関連するアドレス値は、 0x2139 か 0x213a のどちらかを読み込む時にインクリメントされる。 実際には読み込み動作はもう少し複雑で、 これらのレジスタを読み込んだ時、バイト値はワードサイズのバッファから得られる。 このワードバッファは、VRAMアドレスがインクリメントされる前に、 VRAMからロードされる。 データを読み込んだ時のインクリメント量は、0x2115 の下位 4 ビットで設定する。 この変更は、0x2116 ~ 0x2117 を変更した後、 ダミー読み込みを入れると適用され、実際にデータを読み込む前に実行する必要がある。 これらのレジスタと0x2118、0x2119 の 相互作用の詳細については不明。 0x213B - CGDATA (CG データ読み込み) アクセスフラグ 読ワ強V?- D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB Dx D9 D8 g g g r r r r r - b b b b b g g CGRAM の読み込みは OAM の読み込みと似ている。 詳細は 0x2138 参照。 色データは BGR の順に並んでいる。 - は PPU2 のオープンバスを表している。 0x213C - OPHCT (水平スキャンライン位置) アクセスフラグ 読ワ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - - x 0x213D - OPVCT (垂直スキャンライン位置) アクセスフラグ 読ワ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 DF DE DD DC DB DA D9 D8 x x x x x x x x - - - - - - - x これらの値は、0x4201 のビット 7 がセットされている時に 0x2137 を読み込み、 または、0x4201 への書き込みによって 0x4201 のビット 7 をクリアまたはセット、 もしくはコントローラポート 2 のピン 6 を1から0に変更することによってラッチされる。 読み込む値は 9 ビットのみが使用される。 上位バイトの 1 ~ 7 ビットは PPU2 のオープンバス状態になっている。 それぞれのレジスタは、別々に下位/上位バイトのセレクタを保存している。 0x213f が読み込まれる時に、下位/上位セレクタはリセットされる。 (カウンタがラッチされている時にはリセットされない) Hカウンタは 0 ~ 339 の範囲の値を取り、22 ~ 277 が画面に表示される。 Vカウンタは、NTSC モードでは 0 ~ 261 の範囲の値を取り (他の全てのフレームがインターレスの時、262にもなる)、 PAL モードでは 0 ~ 311 (インターレス時312?) の値を取る。 1 ~ 224 の範囲が画面に表示される。 (オーバースキャンが有効の時は 1 ~ 239(?)) 0x213E - STAT77 (PPUステータスフラグとバージョン番号1) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 t r m - v v v v t タイムオーバーフラグ 1 ライン中に 34 より多くのスプライトタイルが見つかった時このフラグがセットされる。 (16x16 のスプライトは、2 つのタイルを持つ) V-Blank の終わりの時点でこのフラグはリセットされる。 r 範囲オーバーフラグ 1 ライン中に 32 より多くのスプライトが見つかった時にこのフラグがセットされる。 V-Blank の終わりの時点でこのフラグはリセットされる。 m マスター/スレーブモード選択 断片的にしか分からない。 S-PPU1 チップの "MASTER" ピンのステータスを表す。 普通の SNES は常に Gnd。 このフラグは常に 0 を返すように見える。 vvvv 5c77 チップのバージョン番号 これまでのところ、1 しか見たことがない。 - になっている部分は、PPU1 のオープンバス状態を表す 0x213F - STAT78 (PPUステータスフラグとバージョン番号2) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 f l - p v v v v f インターレスフラグ V-Blank 毎に反転される。 l 外部ラッチフラグ PPU カウンタがラッチされている時、このフラグがセットされる。 読み込み時にこのフラグはリセットされる。 しかし、0x4201 のビット 7 がセットされる。 p NTSC/PAL モード SNES 本体が PAL の場合、このフラグがセットされる。 NTSC の場合は 0。 vvvv 5C78 チップのバージョン番号 これまでのところ、2 と 3 しか見たことがないが、 1 もあるかもしれない。 - になっている部分は、PPU2 のオープンバス状態を表す 注 このレジスタ読み込み時の副作用として、 0x213c ~ 0x213d の上位/下位バイトセレクタが下位にリセットされる。 0x2140 - APUIO0 (APU IO ポート) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2141 - APUIO1 (APU IO ポート) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2142 - APUIO2 (APU IO ポート) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2143 - APUIO3 (APU IO ポート) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x これらのレジスタは、SPC700 との通信用に使われる。 ここに書き込んだ値は、そのまま読み込み時にも同じ値が 返ってくるわけではない。 書き込んだ値は、SPC700 の 0xF4 ~ 0xF7 レジスタに入り、 読み込み時には SPC700 が操作した値が読み込まれる。 読み込み中に SPC700 が値を書き込んだ場合、 古いものと新しいものを論理 OR した結果が読み込まれる。 実際の読み込みサイクルにどのくらいの時間がかかるのかは分からないが、 6サイクルのメモリアクセス中、最後の3マスターサイクルに 当たるだろうと推測できる。 これらのレジスタは、0x2140 ~ 0x217F の間、 ミラーリングされる。 0x2180 - WMDATA (WRAMデータ読み書き) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2181 ~ 0x2183 でセットされた WRAM アドレスに対して 書き込み/読み込みを行います。 操作ごとにアドレスはインクリメントされます。 読み込み書き込みを組み合わせた場合、動作は不定になりますが、 論理的に動作すると思われます。 DMA で、WRAM からこのレジスタにアクセスすることはできず、 WRAM への書き込み操作は実行されません。 同様に、このレジスタから WRAM にアクセスすることはできず、 書き込まれる値は、オープンバスの値になります。 双方共に、0x2181 ~ 0x2183 はインクリメントされません。 0x2181 - WMADDL (WRAMアドレス (下位)) アクセスフラグ 読書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2182 - WMADDM (WRAMアドレス (中位)) アクセスフラグ 読書中強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x2183 - WMADDH (WRAMアドレス (上位)) アクセスフラグ 読書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x ここには、0x2180 からアクセスされるアドレスを入れます。 WRAM は SNES メモリスペースの $7E 0000 ~ $7F FFFF と、 バンク 0x00 ~ 0x3F, 0x80 ~ 0xBF の 0x0000 から 0x1FFF にもマップされています。 いくつかのドキュメントで、これら 0x2181 ~ 0x2183 のレジスタは 書き込みだけでなく、読み込みもできるように書かれていますが、それは誤りです。 読み込み時にはオープンバスの値が返ります。 DMA で、WRAM からこれらのレジスタに対してアクセスはできませんが、 他の場合は DMA の書き込み動作が通常通り行われます。 これは、DMA で 0x2180 を通して ROM内 の 1 つのテーブルから RAM の連続した領域に書き込むことができるということです。 このレジスタの値は、インクリメント時にページ境界をまたぐことはありません。 0x4016 - JOYSER0 (NES形式ジョイパッドアクセスポート1) アクセスフラグ 読書バ強VH常 読み込み時 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - c a 書き込み時 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - - l 0x4017 - JOYSER1 (NES形式ジョイパッドアクセスポート2) アクセスフラグ 読?バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 - - - 1 1 1 d b これらのレジスタは、本体前面のコントローラポートに直接繋がっている。 l このビットを書き込むと、2つのポートを両方ともラッチ(Latch)する。 1 がセットされると、Latch ピンが High になる。 a/b Data1 ピンの内容 c/d Data2 ピンの内容 0x4016 を読み込む時、コントローラポート1のClockピンはLowになる。 本体がData1、Data2を読み込み終わった後、ClockはHighに戻る。 0x4017 を読み込む時は、ポート2に対して同じことが起こる。 注 0x4017 の 1になっているところは Gnd に繋がっており、常に1になる。 普通のジョイパッドは次の順番でデータを返す。 B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R, 0, 0, 0, 0 ラッチされると順番はクリアされる? 参照 ラッチ回路 ディジタル電子回路において、論理信号を通過させたり保持させたりする機能を有する回路。 門などの関門の開閉に擬えた符牒として、おもにアマチュア工作方面で見受けられる。 Wikipediaより 0x4200 - NMITIMEN (割り込み有効フラグ) アクセスフラグ 書バ強VH? D7 D6 D5 D4 D3 D2 D1 D0 n - y x - - - a n NMI 有効フラグ 0 の場合、NMI は発生しません。 1 の場合、NMI は V-Blank 開始時に発生します。 NMI は V カウンタが 0xE1 (225) の時に若干遅れて発生します。 オーバースキャンが有効の時は、たぶん 0xF0 (240) で発生します。 詳しくは 0x2133 を参照してください。 x/y IRQ 有効 0/0 = IRQ は発生しない 0/1 = V カウンタが 0x4209 ~ 0x420a で設定された値に達した時 IRQ 発生 1/0 = H カウンタが 0x4207 ~ 0x4208 で設定された値に達した時 IRQ 発生 1/1 = H カウンタが 0x4207 ~ 0x4208 で設定された値に達し、かつ V カウンタが 0x4209 ~ 0x420a で設定された値と同じなら IRQ 発生 a 自動ジョイパッド読み込み有効 1 の時、0x4218 ~ 0x421f は V カウンタが 0xE3 (227) の時に 自動的に更新されます。 (オーバースキャンが有効の時はたぶん 0xF2 (242)) いくつかのゲームはここから値を読み込もうとしますが、 オープンバス値が読み込まれているものと考えられます。 このレジスタは、電源 ON 時、リセット時に 0x00 に初期化されます。 0x4201 - WRIO (プログラマブルIOポート(出力)) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 a b x x x x x x 基本的にこれは 8 ビットの I/O ポートですが、 b はコントローラポート 1 の 6 ピンに接続されていて、 a はコントローラポート 2 の 6 ピンと、PPU のラッチラインに接続されています。 a が 1 の時に 0 を書き込むと、0x2137 読み込み時のように、 H・Vカウンタがラッチされます (0 に遷移する時にラッチが起こる)。 a が 0 の時は、ラッチは起こりません。 このレジスタの他の変化は不明です。 0x4213 は、この I/O ポートの対になる入力用ポートです。 IO ポートは電源 ON 時に全て 1 が入っているかのように初期化されます。 リセット時はたぶん変化ありません。 0x4202 - WRMPYA (乗算用の被乗数) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 m m m m m m m m 0x4203 - WRMPYB (乗算用の乗数) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 m m m m m m m m 0x4202 に書き込みした後、 0x4203 に書き込む。 0x4203 に書き込んだ 8 "マシンサイクル" (およそ 48 マスターサイクル) 後に、 乗算した結果を 0x4216 ~ 0x4217 から読み込むことができる。 この動作で 0x4202 は変化することはなく、 そのままリセットせずに 0x4203 に違う値を書き込むと、 新しい結果が得られる。 乗算は unsigned の値で行われる。 電源ON時に 0x4202 は 0xff で初期化され、 リセット時には変化しない。 0x4204 - WRDIVL (除算用の被除数 (下位)) アクセスフラグ 書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 d d d d d d d d 0x4205 - WRDIVH (除算用の被除数 (上位)) アクセスフラグ 書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 d d d d d d d d 0x4206 - WRDIVB (除算用の除数) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 b b b b b b b b 0x4204, 0x4205 に書き込んでから 0x4206 に書き込みます。 0x4206 に書き込んだ 16 "マシンサイクル" (およそ 96 マスターサイクル) 後に、 除算結果の商を 0x4214 ~ 0x4215 から、 余りを 0x4216 ~ 0x4217 から読み込むことができます。 0x4202 と同様に、たぶん 0x4204, 0x4205 もリセットされません。 除算は unsigned の値で行われます。 0 を除数に割り算した時 (Division by 0) は、商が 0xFFFF になり、 余りが 0x4204, 0x4205 の値になります。 電源ON時に、0x4204, 0x4205 は 0xffff で初期化されます。 リセット時には変化しません。 0x4207 - HTIMEL (Hカウントタイマー (下位)) アクセスフラグ 書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 h h h h h h h h 0x4208 - HTIMEH (Hカウントタイマー (上位)) アクセスフラグ 書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - - h 0x4200 のビット 4 がセット、ビット 5 がクリアになっていて、 H カウンタがこのレジスタに設定された値に達した時、 スキャンライン毎に IRQ が発生します。 ビット 4, 5 が両方ともセットされている時は、 V カウンタが 0x4209 ~ 0x420a にセットされた値と同じ時だけ IRQ が発生します。 H カウンタは 0 ~ 339 の範囲で変化します。 これより大きい値がセットされた時には、IRQ は発生しません。 電源ON時に、HTIME は 0x1ff で初期化されます。 リセット時には変化しません。 0x4209 - VTIMEL (Vカウントタイマー (下位)) アクセスフラグ 書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 v v v v v v v v 0x420A - VTIMEH (Vカウントタイマー (上位)) アクセスフラグ 書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - - v 0x4200 のビット 5 がセット、ビット 4 がクリアになっていて、 V カウンタがこのレジスタに設定された値に達した時に IRQ が発生します。 ビット 4, 5 が両方ともセットされている時は、 V カウンタがこのレジスタにセットされた値と同じ、 かつ H カウンタが 0x4207 ~ 0x4208 で設定した値に 達した時に IRQ が発生します。 テレビの方式が NTSC の時、V カウンタは 0 ~ 261 の値を取ります。 (他の全てのフレームでインターレスモードが有効の時、262 にもなる) PAL の時は 0 ~ 311 の値を取ります (インターレス時 312?)。 これらより大きい値を設定した時、IRQ は発生しません。 電源ON時に、VTIME は 0x1ff で初期化されます。 リセット時には変化しません。 0x420B - MDMAEN (DMA有効) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 7 6 5 4 3 2 1 0 7/6/5/4/3/2/1/0 指定された DMA チャネルを有効にします。 CPU は全ての DMA の転送が終わるまで一時停止されます。 DMA は(たぶん) 0 ~ 7 の順番で実行されます。 詳細は 0x43x0 ~ 0x43xA を参照してください。 DMA転送中にHDMAの初期化または転送が発生した場合、 DMAはその間停止されます。 現在使用中のDMAチャネルと同じチャネルでHDMAが発生した場合は、 DMAはすぐさま停止され、その時使われていたレジスタの値を使って HDMAは転送を継続します。他のDMAチャネルは影響を受けません。 電源ON時、リセット時にこのレジスタは 0x00 で初期化されます。 0x420C - HDAMEX (HDMA有効) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 7 6 5 4 3 2 1 0 7/6/5/4/3/2/1/0 指定された HDMA チャネルを有効にします。 HDMA は(たぶん) 0 ~ 7 の順番で実行されます。 詳細は 0x43x0 ~ 0x43xA を参照してください。 DMA転送中にHDMAの初期化または転送が発生した場合、 DMAはその間停止されます。 現在使用中のDMAチャネルと同じチャネルでHDMAが発生した場合は、 DMAはすぐさま停止され、その時使われていたレジスタの値を使って HDMAは転送を継続します。他のDMAチャネルは影響を受けません。 フレーム処理中にHDMAチャネルが有効になった場合、 そのチャネルは次のHDMAポイントで開始されます。 HDMAレジスタの初期化処理は、スキャンライン 0 の HDMAポイントの 前でのみ発生するので、HDMA を有効にする前に これらのレジスタを手動で初期化する必要があります。 フレーム中にすでに停止されているチャネルは、 この方法によって再度開始することはできません。 チャネル指定ビットに 0 を書き込むとき、現行の HDMA チャネルは停止されます。 この転送は、1 を書き込むことで再開することができます。 電源ON時、リセット時にこのレジスタは 0x00 で初期化されます。 0x420D - MEMSEL (ROMアクセススピード) アクセスフラグ 書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 - - - - - - - f f FastROM 選択 SNESはマスタークロックに 21.477 MHz (1.89e9/88 Hz) を使います。 標準では、ROMアクセスの度に 8 マスターサイクルの時間がかかります。 このビットがセットされている時、バンク 0x80 ~ 0xFF に対する ROM アクセスは 6 マスターサイクルになります。 電源ON時(リセット時も?)に、このレジスタは 0x00 で初期化されます。 詳細は memmap.txt を参照してください。 0x420E - (未使用?) 0x420F - (未使用?) 0x4210 - RDNMI (NMIフラグと5A22のバージョン番号) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 n - - - v v v v n NMIフラグ このフラグは、V-Blank 開始時にセットされる (現時点では、Hカウンタの値が 0x28 ~ 0x4E の間にある時だと考えている)。 読み込み時、または V-Blank 終了時にクリアされる。 おそらく、このレジスタは NMI の最中に読み込まれる必要があるだろう。 このフラグは、0x4200 のビット 7 には影響を受けない。 vvvv 5A22チップバージョン番号 これまで 2 になっているものしか見たことないが、 1 もあるだろう 電源ON時またはリセット時に、NMI はクリアされる。 - になっているビットはオープンバス。 0x4211 - TIMEUP (H/Vカウントタイマー用IRQフラグ) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 i - - - - - - - i IRQフラグ このフラグは、IRQ が発行された後にセットされる (現在のところ、0x4210 の NMI フラグと同じような遅れが発生するように見えている)。 読み込み/書き込み時にクリアされる。 おそらく、このレジスタは IRQ ハンドラ内で読み込む必要があります。 このレジスタに対する読み込み操作が、CPU の IRQ ラインを 本当にクリアするのかどうか疑わしい。 説明はないが、他のドキュメントでは このレジスタが読み込み/書き込み可能と書かれている。 電源ON時、リセット時に IRQ はクリアされる。 - のビットはオープンバス。 0x4212 - HVBJOY (H/V-Blankフラグとジョイスティック有効フラグ) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 v h - - - - - a v V-Blank フラグ V-Blank中はセットされている。V-Blankの外ではクリアされる。 セットされるタイミングは、Vカウンタが 0xE1(225) かつ Hカウンタが 0x16 ~ 0x17 (22 ~ 23) の時で、 クリアされるタイミングは、Vカウンタが 0 かつ Hカウンタが 0x1E (30) の時。 h H-Blank フラグ H-Blank中はセットされている。H-Blankの外ではクリアされる。 セットされるタイミングは、Hカウンタが 0x121 ~ 0x122 (289 ~ 290) の時で、 クリアされるタイミングは、Hカウンタが 0x12 ~ 0x18 (18 ~ 24) の時。 a 自動ジョイパッドステータス 自動ジョイパッド読み込み時にセットされる。 完了時にクリアされる。 典型的に、これは V-Blank 開始時にセットされ、 3 スキャンライン後に完了する。 説明はないが、他のドキュメントでは このレジスタが読み込み/書き込み可能と書かれている。 0x4213 - RDIO (プログラマブルIOポート(入力)) アクセスフラグ 読バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 a b x x x x x x このレジスタは、I/O ポートからデータを読み込む時に使う。 0x4201 から 0 をセットした時、このレジスタから 0 が読み込まれる。 0x4201 から 1 をセットした時は、このレジスタから 0 または 1 が読み込まれる。 これは、I/Oポートに接続されたデバイスがこのビットに 0 をセットするかどうかに 関連している。 b はコントローラポート 1 の 6 ピンに接続されていて、 a はコントローラポート 2 の 6 ピンと、PPU のラッチラインに接続されています。 0x4201 は、この I/O ポートの対になる出力用ポートです。 0x4214 - RDDIVL (除算結果の商 (下位)) アクセスフラグ 読下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 q q q q q q q q 0x4215 - RDDIVH (除算結果の商 (上位)) アクセスフラグ 読上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 q q q q q q q q 0x4204,0x4205 に書き込んだ後に 0x4206 に書き込んだ時、 0x4206 への書き込みから 16 マシンサイクル (およそ 96 マスターサイクル) 後に このレジスタから除算結果の商を読み込むことができる。 剰余は 0x4216,0x4217 から読み込む。 除算は、unsigned で行われる。 0x4216 - RDMPYL (乗算結果または除算結果の剰余 (下位)) アクセスフラグ 読下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x4217 - RDMPYH (乗算結果または除算結果の剰余 (上位)) アクセスフラグ 読上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 x x x x x x x x 0x4202 に書き込んだ後に 0x4203 に書き込んだ時、 0x4203 への書き込みから 8 マシンサイクル (およそ 48 マスターサイクル) 後に このレジスタから乗算結果 (積) を読み込むことができる。 0x4204,0x4205 に書き込んだ後に 0x4206 に書き込んだ時、 0x4206 への書き込みから 16 マシンサイクル (およそ 96 マスターサイクル) 後に このレジスタから除算結果の余り (剰余) を読み込むことができる。 乗算、除算ともに unsigned で行われる。 0x4218 - JOY1L (コントローラポート 1 の Data1(下位)) アクセスフラグ 読下強VH常 0x4219 - JOY1H (コントローラポート 1 の Data1(上位)) アクセスフラグ 読上強VH常 0x421A - JOY2L (コントローラポート 2 の Data1(下位)) アクセスフラグ 読下強VH常 0x421B - JOY2H (コントローラポート 2 の Data1(上位)) アクセスフラグ 読上強VH常 0x421C - JOY3L (コントローラポート 1 の Data2(下位)) アクセスフラグ 読下強VH常 0x421D - JOY3H (コントローラポート 1 の Data2(上位)) アクセスフラグ 読上強VH常 0x421E - JOY4L (コントローラポート 2 の Data2(下位)) アクセスフラグ 読下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 a x l r 0 0 0 0 0x421F - JOY4H (コントローラポート 2 の Data2(上位)) アクセスフラグ 読上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 b y e t U D L R 上の表は、ジョイパッドの時のみ当てはまる (ジョイパッド以外のものを接続した時には当てはまらない)。 自動ジョイパッド読み込みは、0x4016,0x4017 を 16 回読み込み、 0x4218 ~ 0x421F に値をセットする。 a/b/x/y/l/r/e/t A/B/X/Y/L/R/Select/Start ボタンのステータス U/D/L/R Up/Down/Left/Right の十字キーのステータス L/R の内、どちらかのみ、U/D の内、どちらかのみがセットされる。 0x4200 のビット 0 の、自動ジョイパッド読み込みフラグが 有効になっている時のみこれらのレジスタの値が更新される。 更新中は、0x4212 のビット 0 の、 自動ジョイパッド読み込みステータスがセットされる。 この間に読み込み操作を行うと、不正な値が返る。 詳しくは コントローラ の項目を参照してください。 アドレスと名前の中の x には、DMAのチャネル番号が入る。 DMA・HDMA共に 0 ~ 7 の 8 個のチャネルがある。 0x43x0 - DMAPx (DMAチャネル調整) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 d a - i f t t t d 転送方向 0の時、CPUメモリから読み込み、PPUレジスタに書き込む。 1の時はその逆。 このビットはHDMAに影響する。 普通にテーブルを読み込んで、バスBからバスAに書き込む時に 間接モードがより使いやすくなる。 読み込みカウントをテーブルから読んで、値をテーブルに書き込もうとするとき、 直接モードも動くと思う。 a HDMAアドレッシングモード 0の時、HDMAテーブルに転送用データが入る(直接モード)。 1の時、HDMAテーブルにポインタが入る(間接モード)。 このフラグは、DMAには影響しない。 i DMAアドレスインクリメント 0の時、1バイトごとにDMAアドレスがインクリメントされる。 1の時はデクリメントされる。 このフラグは、HDMAには影響しない。 f DMA固定転送 0の時、ビット4で指定された値にアドレスが固定される。 1の時、DMAアドレスは固定されない。 このフラグは、HDMAには影響しない。 ttt 転送モード 値 モード 内容 000 1レジスタ1書き込み 1 バイト p 001 2レジスタ1書き込み 2 バイト p, p+1 010 1レジスタ2書き込み 2 バイト p, p 011 2レジスタ2書き込み(それぞれ) 4 バイト p, p, p+1, p+1 100 4レジスタ1書き込み 4 バイト p, p+1, p+2, p+3 101 2レジスタ2書き込み(交互) 4 バイト p, p+1, p, p+1 110 1レジスタ2書き込み 2 バイト p, p 111 2レジスタ2書き込み(それぞれ) 4 バイト p, p, p+1, p+1 HDMA転送中にこのレジスタに書き込みを行うと、未知の動作をするか、 あるいは次の転送時に変更が適用される。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43x1 - BBADx (DMA転送先B-バスアドレス) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 p p p p p p p p このレジスタは、アクセスするBバスアドレスを、 $00 2100 ~ $00 21ff の間で指定する。 2~4個のレジスタを操作するモードでは、0x21ff → 0x2100 に ラップされる。0x2200 にアクセスされるわけではない。 HDMA転送中にこのレジスタに書き込みを行うと、未知の動作をするか、 あるいは次の転送時に変更が適用される。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43x2 - A1TxL (DMA転送元A1テーブルアドレス下位) アクセスフラグ 読書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 l l l l l l l l A1TxL・A1TxH・A1Bxはセットで使用する。 0x43x3 - A1TxH (DMA転送元A1テーブルアドレス上位) アクセスフラグ 読書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 h h h h h h h h A1TxL・A1TxH・A1Bxはセットで使用する。 0x43x4 - A1Bx (DMA転送元A-バステーブルバンク) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 b b b b b b b b A1TxL・A1TxH・A1Bxはセットで使用する。 これらは、DMA転送用の「アドレス」開始位置に バスAアドレスを指定するか、もしくは HDMA転送用にHDMAテーブルの開始位置を指定する。 バスAはバスBレジスタにアクセスしない。 このアドレスに$00 2100を指定した場合、オープンバスの値が返る。 HDMA転送中にこのレジスタに書き込みを行うと、未知の動作をする。 今のところ、0x43x4のみが転送に影響するだろうと考えられている。 値の変更は、次のHDMA初期化時に適用される。 DMA転送中は、0x43x4 の設定でアドレスが固定されていない場合、 0x43x0 に設定された方向で 0x43x2/3 の値が インクリメントまたはデクリメントされる。 これらのレジスタはHDMAには影響しない。 このレジスタは、電源オン時に 0xFF にセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43x5 - DASxL (DMAサイズ/HDMA間接アドレス下位バイト) アクセスフラグ 読書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 l l l l l l l l DASxL・DASxH・DASBxはセットで使用する。 0x43x6 - DASxH (DMAサイズ/HDMA間接アドレス上位バイト) アクセスフラグ 読書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 h h h h h h h h DASxL・DASxH・DASBxはセットで使用する。 0x43x7 - DASBx (HDMA間接アドレスバンクバイト) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 b b b b b b b b DASxL・DASxH・DASBxはセットで使用する。 DMAの時、0x43x5/6 は転送バイト数を指す。 1が指定された場合、転送モードで2か4のレジスタの転送が 指定されている時でも、1バイトのみ転送される。 (5が指定された場合、最初の転送で4つのレジスタが転送され、 2回目は1つだけが転送される。) 0x0000が指定された場合は、0x10000バイトの転送を指す。 0回ではないので注意。 DMA転送中は 0x43x5/6 がデクリメントされ、 完了時にはいつも0になる。 HDMAの時、0x43x7には間接アドレッシングモードのバンクバイトを指定する。 間接アドレスは 0x43x5/6 にコピーされ、インクリメントされる。 直接HDMAの時には、これらのレジスタは使用されない。 間接HDMAの最中に 0x43x7 に値が書き込まれた時、変更は次の転送時に適用される。 0x43x5/6 に書き込まれた場合も、同じように次の転送時に適用されるように動作するが、 こちらの場合は、繰り返しモードが指定された時にのみ適用される。 (普通のモードの場合、間接アドレスは転送開始前にテーブルから読み込まれる) 直接HDMAモードでは何も起こらないだろう。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43x8 - A2AxL (HDMA用A2テーブルアドレス下位バイト) アクセスフラグ 読書下強VH常 D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a a a A2AxL・A2AxHはセットで使用する。 0x43x9 - A2AxH (HDMA用A2テーブルアドレス上位バイト) アクセスフラグ 読書上強VH常 D7 D6 D5 D4 D3 D2 D1 D0 a a a a a a a a A2AxL・A2AxHはセットで使用する。 フレーム開始時、0x43x2 ~ 0x43x3 の値は全てのアクティブなHDMAチャネルにコピーされ、 テーブルの値が読み込まれてこのレジスタの値は更新される。 HDMAをフレーム処理中に開始しようとした場合 (もしくはテーブルをフレーム処理中に変更した場合)、 このレジスタに値が書き込まれている必要がある。 フレーム処理中にこのレジスタに書き込まれた内容は、 次のスキャンラインで適用される。 このレジスタはDMAでは使われない。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43xA - NLTRx (HDMA転送行数) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 r c c c c c c c r 繰り返し選択 1の時、HDMA 転送はスキャンライン毎に繰り返される。 ほとんどの場合、このレジスタの値はテーブルからロードされる。 このバイト(と間接HDMAアドレス)の値は、カウンタ値が0に到達した時に テーブルからリロードされる。 ccccccc 行カウント この値は、スキャンライン毎にデクリメントされる。 0に到達した時、このレジスタに対してHDMAテーブルから1バイト分ロードされる。 (そして、可能であれば間接HDMAアドレスは 0x43x5/6 からロードされる。) 注(奇妙な動作) このレジスタは、r の状態と c が 0 になっているかをチェックする前に デクリメントされる。 なので、0x80 をこのレジスタにセットすると、"0行を繰り返し有り" で 実行するのではなく、"128行を繰り返し無し" で実行してしまう。 同様に、0x00 の指定は "チャネルの停止" を意味せず、 "128行を繰り返し有り" で実行してしまう。 このレジスタは、V-Blank 終了時にアクティブな全てのHDMAチャネルで初期化される。 フレーム処理中にHDMAを開始しようとした場合、このレジスタを初期化しなければならない。 HDMA転送処理中に行カウント値か繰り返しフラグを変更した時は、 次のスキャンラインで変更が適用される。 繰り返しフラグは、次の転送期間の終了まで変更が適用されないので注意すること。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 参照 DMAとHDMA 0x43xB - ????x (不明) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 ? ? ? ? ? ? ? ? 0x43xB と 0x43xF は同じレジスタを指す。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。 0x43xF - ????x (不明) アクセスフラグ 読書バ強VH常 D7 D6 D5 D4 D3 D2 D1 D0 ? ? ? ? ? ? ? ? 0x43xB と 0x43xF は同じレジスタを指す。 このレジスタは、電源オン時に0xffにセットされる。リセット時は変更されない。